Drupal - How to load content in a div with ajax?


I've come up with a working solution. It might not be the best approach but it works.

You need to create your routing file:


  path: 'path-with-data'
    _controller: '\Drupal\my_module\Controller\MyController::Render'
    _access: 'TRUE'

Creating the controller for your page



namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use \Symfony\Component\HttpFoundation\Response;

 * An example controller.
class MyController extends ControllerBase {

   * {@inheritdoc}
  public function Render() {
    $build = array(
      '#type' => 'markup',
      '#markup' => t('Hello World!'),
    // This is the important part, because will render only the TWIG template.
    return new Response(render($build));


And you only need to call in javascript


An this will be the output once the code is executed:

<div id="my-div">Hello World!</div>


  • Drupal 8 module - How to use AJAX?
  • Drupal8:Basic Jquery Ajax custom module controller

This is exactly what you need.

var endpoint = Drupal.url('modal/get-content');
Drupal.ajax({ url: endpoint }).execute();

where endpoint is the URL of your route. So you have controller for your route and this controller has AjaxResponse

public function getContent($modal_id) {
  $response = new AjaxResponse();

  $selector = '.modal.in .modal-body';

  // You can use markup, rendreable array, getForm via form_builder service.
  $content = [
    '#markup' => '....',

  $response->addCommand(new InvokeCommand($selector, 'removeClass', ['spinner-loading']));
  $response->addCommand(new HtmlCommand($selector, $content));

  return $response;

Add what you need to your build array, and to render without the Page template, you can pass to a new Response object:

$build['view'] = [
  '#type' => 'view',
  '#name' => 'my_view',
  '#display_id' => 'block_1',
  '#arguments' => $view_arguments,

$rendered = \Drupal::service('renderer')->renderRoot($build);

$response = new Response();
return $response;