I have a custom controller action that returns the HTML for a search result. The action is invoked via AJAX on the search page and the results are inserted into the page body.

The problem is that a dynamic page cache entry is created for this controller action and it's not "busted" when the query string changes, so old results are always returned:

  public function basicPeopleSearch(Request $request) {
    $search = $request->query->get('search');
    $build = [];
    if (!empty($search)) {
      // Get search results and add them to the render array.
      $results = \Drupal::getContainer()->get('pu_search.people_search')->basicSearch($search);

      foreach ($results as $result) {
        $build[] = [
          '#theme' => 'pu_search_person',
          '#person' => $result,

    // The results will differ based on the "search" query string parameter.
    $build['#cache'] = [
      'contexts' => [

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

I suspect this has something to do with how I'm actually returning the response or rendering the output?

1 Answer 1


You have to add the cacheable metadata from the render array to the response:

use Drupal\Core\Cache\CacheableMetadata;

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.