diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index fefe9f3..fa32e05 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -64,6 +64,7 @@
           element_settings.event = 'click';
         }
         element_settings.dialogType = $(this).data('dialog-type');
+        element_settings.drupalDialogRenderer = $(this).data('dialog-renderer');
         element_settings.dialog = $(this).data('dialog-options');
         element_settings.base = $(this).attr('id');
         element_settings.element = this;
@@ -312,6 +313,8 @@
    *   Options for {@link Drupal.dialog}.
    * @prop {string} [dialogType]
    *   One of `'modal'` or `'dialog'`.
+   * @prop {string} [drupalDialogRenderer]
+   *   Renderer for the dialog, 'offcanvas' supported.
    * @prop {string} [prevent]
    *   List of events on which to stop default action and stop propagation.
    */
@@ -526,7 +529,11 @@
     else {
       ajax.options.url += '&';
     }
-    ajax.options.url += Drupal.ajax.WRAPPER_FORMAT + '=drupal_' + (element_settings.dialogType || 'ajax');
+    var wrapper = 'drupal_' + (element_settings.dialogType || 'ajax');
+    if (element_settings.drupalDialogRenderer) {
+      wrapper += '.' + element_settings.drupalDialogRenderer;
+    }
+    ajax.options.url += Drupal.ajax.WRAPPER_FORMAT + '=' + wrapper;
 
     // Bind the ajaxSubmit function to the element event.
     $(ajax.element).on(element_settings.event, function (event) {
diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js
index 36f85b0..650af46 100644
--- a/core/modules/outside_in/js/outside_in.js
+++ b/core/modules/outside_in/js/outside_in.js
@@ -214,26 +214,17 @@
     attach: function () {
 
       $(toggleEditSelector).once('outsidein').on('click.outsidein', toggleEditMode);
-
-      var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog';
-      var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_offcanvas';
-      // Loop through all Ajax links and change the format to dialog-offcanvas when
-      // needed.
+      // Loop through all Ajax links to set active editable ID.
       Drupal.ajax.instances
         .filter(function (instance) {
           var hasElement = instance && !!instance.element;
           var rendererOffcanvas = false;
-          var wrapperOffcanvas = false;
           if (hasElement) {
             rendererOffcanvas = $(instance.element).attr('data-dialog-renderer') === 'offcanvas';
-            wrapperOffcanvas = instance.options.url.indexOf('drupal_dialog_offcanvas') === -1;
           }
-          return hasElement && rendererOffcanvas && wrapperOffcanvas;
+          return hasElement && rendererOffcanvas;
         })
         .forEach(function (instance) {
-          // @todo Move logic for data-dialog-renderer attribute into ajax.js
-          //   https://www.drupal.org/node/2784443
-          instance.options.url = instance.options.url.replace(search, replace);
           // Check to make sure existing dialogOptions aren't overridden.
           if (!('dialogOptions' in instance.options.data)) {
             instance.options.data.dialogOptions = {};
diff --git a/core/modules/outside_in/outside_in.services.yml b/core/modules/outside_in/outside_in.services.yml
index 48f5824..6d4264c 100644
--- a/core/modules/outside_in/outside_in.services.yml
+++ b/core/modules/outside_in/outside_in.services.yml
@@ -3,7 +3,7 @@ services:
     class: Drupal\outside_in\Render\MainContent\OffCanvasRender
     arguments: ['@title_resolver', '@renderer']
     tags:
-      - { name: render.main_content_renderer, format: drupal_dialog_offcanvas }
+      - { name: render.main_content_renderer, format: drupal_dialog.offcanvas }
 
   outside_in.manager:
     class: Drupal\outside_in\OutsideInManager
diff --git a/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.info.yml b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.info.yml
new file mode 100644
index 0000000..f7544e7
--- /dev/null
+++ b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Database Renderer Test'
+type: module
+description: 'Support module for Dialog Renderer tests.'
+core: 8.x
+package: Testing
+version: VERSION
diff --git a/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.routing.yml b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.routing.yml
new file mode 100644
index 0000000..3cfbde0
--- /dev/null
+++ b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.routing.yml
@@ -0,0 +1,15 @@
+dialog_renderer_test.links:
+  path: '/dialog_renderer-test-links'
+  defaults:
+    _controller: '\Drupal\dialog_renderer_test\Controller\TestController::linksDisplay'
+    _title: 'Links'
+  requirements:
+    _access: 'TRUE'
+
+dialog_renderer_test.modal_content:
+  path: '/dialog_renderer-content'
+  defaults:
+    _controller: '\Drupal\dialog_renderer_test\Controller\TestController::modalContent'
+    _title: 'Thing 1'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.services.yml b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.services.yml
new file mode 100644
index 0000000..1bf58fa
--- /dev/null
+++ b/core/modules/system/tests/modules/dialog_renderer_test/dialog_renderer_test.services.yml
@@ -0,0 +1,6 @@
+services:
+  main_content_renderer.wide_modal:
+    class: Drupal\dialog_renderer_test\Render\MainContent\WideModalRenderer
+    arguments: ['@title_resolver', '@renderer']
+    tags:
+      - { name: render.main_content_renderer, format: drupal_modal.wide }
diff --git a/core/modules/system/tests/modules/dialog_renderer_test/src/Controller/TestController.php b/core/modules/system/tests/modules/dialog_renderer_test/src/Controller/TestController.php
new file mode 100644
index 0000000..573a656
--- /dev/null
+++ b/core/modules/system/tests/modules/dialog_renderer_test/src/Controller/TestController.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Drupal\dialog_renderer_test\Controller;
+
+use Drupal\Core\Url;
+
+/**
+ * Test controller display modal links and content.
+ */
+class TestController {
+
+  /**
+   * Return modal content.
+   *
+   * @return array
+   *   Render array for display in modal.
+   */
+  public function modalContent() {
+    return [
+      '#type' => 'markup',
+      '#markup' => 'Look at me in a modal!',
+    ];
+  }
+
+  /**
+   * Displays test links that will open in the modal dialog.
+   *
+   * @return array
+   *   Render array with links.
+   */
+  public function linksDisplay() {
+    return [
+      'normal_modal' => [
+        '#title' => 'Normal Modal!',
+        '#type' => 'link',
+        '#url' => Url::fromRoute('dialog_renderer_test.modal_content'),
+        '#attributes' => [
+          'class' => ['use-ajax'],
+          'data-dialog-type' => 'modal',
+        ],
+        '#attached' => [
+          'library' => [
+            'core/drupal.ajax',
+          ],
+        ],
+      ],
+      'wide_modal' => [
+        '#title' => 'Wide Modal!',
+        '#type' => 'link',
+        '#url' => Url::fromRoute('dialog_renderer_test.modal_content'),
+        '#attributes' => [
+          'class' => ['use-ajax'],
+          'data-dialog-type' => 'modal',
+          'data-dialog-renderer' => 'wide',
+        ],
+        '#attached' => [
+          'library' => [
+            'core/drupal.ajax',
+          ],
+        ],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php b/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php
new file mode 100644
index 0000000..6309f24
--- /dev/null
+++ b/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\dialog_renderer_test\Render\MainContent;
+
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\OpenModalDialogCommand;
+use Drupal\Core\Render\MainContent\DialogRenderer;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Wide main content renderer for modal dialog requests.
+ *
+ * This test class is copied from \Drupal\Core\Render\MainContent\ModalRenderer
+ * to demonstrate selecting a different render via 'data-dialog-renderer' link
+ * attribute.
+ */
+class WideModalRenderer extends DialogRenderer {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) {
+    $response = new AjaxResponse();
+
+    // First render the main content, because it might provide a title.
+    $content = drupal_render_root($main_content);
+
+    // Attach the library necessary for using the OpenModalDialogCommand and set
+    // the attachments for this Ajax response.
+    $main_content['#attached']['library'][] = 'core/drupal.dialog.ajax';
+    $response->setAttachments($main_content['#attached']);
+
+    // If the main content doesn't provide a title, use the title resolver.
+    $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject());
+
+    // Determine the title: use the title provided by the main content if any,
+    // otherwise get it from the routing information.
+    $options = $request->request->get('dialogOptions', []);
+    // Override width option.
+    $options['width'] = 700;
+
+    $response->addCommand(new OpenModalDialogCommand($title, $content, $options));
+    return $response;
+  }
+
+}
diff --git a/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php b/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php
new file mode 100644
index 0000000..ce234a1
--- /dev/null
+++ b/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\system\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests that dialog links use different renderer services.
+ *
+ * @group system
+ */
+class ModalRendererTest extends JavascriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'dialog_renderer_test'];
+
+  /**
+   * Tests that links respect 'data-dialog-renderer' attribute.
+   */
+  public function testModalRenderer() {
+    $session_assert = $this->assertSession();
+    $this->drupalGet('/dialog_renderer-test-links');
+    $this->clickLink('Normal Modal!');
+    $session_assert->assertWaitOnAjaxRequest();
+    $session_assert->elementAttributeNotContains('css', '.ui-dialog', 'style', 'width: 700px;');
+    $this->drupalGet('/dialog_renderer-test-links');
+    $this->clickLink('Wide Modal!');
+    $session_assert->assertWaitOnAjaxRequest();
+    $session_assert->elementAttributeContains('css', '.ui-dialog', 'style', 'width: 700px;');
+  }
+
+}
