How to handle cache metadata in a cacheable response? 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-&gt;query-&gt;get('search');
    $build = [];
    if (!empty($search)) {
      // Get search results and add them to the render array.
      $results = \Drupal::getContainer()-&gt;get('pu_search.people_search')-&gt;basicSearch($search);

      foreach ($results as $result) {
        $build[] = [
          '#theme' =&gt; 'pu_search_person',
          '#person' =&gt; $result,
        ];
      }
    }

    // The results will differ based on the "search" query string parameter.
    $build['#cache'] = [
      'contexts' =&gt; [
        'url.query_args:search',
      ],
    ];

    $rendered = \Drupal::service('renderer')-&gt;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?
You have to add the cacheable metadata from the render array to the response:

use Drupal\Core\Cache\CacheableMetadata;

  $rendered = \Drupal::service('renderer')-&gt;renderRoot($build);
  $response = new CacheableResponse($rendered);
  $response-&gt;addCacheableDependency(CacheableMetadata::createFromRenderArray($build));
  return $response;