How to set different cache mobile and desktop based on header HTTP for one URL? Here is the problem we're facing :

I have one url : www.example.com/my-page with a different HTML footer for mobile and desktop.

To know which HTML to use we look for HTTP Headers sent by one CDN (Akamaï) => $_SERVER['HTTP_X_AKAMAI_DEVICE_CHARACTERISTICS'].

What we want to achieve is to have cache for both mobile and desktop based on that HTTP Header since the URL is the same. Is it possible ? And if yes, how to do it ?

Having both HTML in the DOM is not an option here, for performance reasons.

We played with contexts in the #cache array but no success here. Maybe with using tags, but not sure about how to use it.

Any help would be greatly appreciated.
You have to add a cache context to the page:

/**
 * Implements hook_preprocess_HOOK() for the page template.
 */
function mymodule_preprocess_page(&amp;$variables) {
  if ( ... ) {  // check if this is the page
    $variables['#cache']['contexts'][] = 'headers:X-Something';
  }
}


This adds probably too many variations, so you might need a custom cache context to only vary by two conditions, mobile or desktop. Extend RequestStackCacheContextBase, so that the request stack is already injected and return either 'dc.mobile' or 'dc.desktop':

  public function getContext() {
    $request = $this-&gt;requestStack-&gt;getCurrentRequest();
    $header = $request-&gt;headers-&gt;get('HTTP_X_AKAMAI_DEVICE_CHARACTERISTICS');
    if (...) {   // check $header for mobile
      return 'dc.mobile';
    }
    else {
      return 'dc.desktop';
    }
  }


This is a tagged service (tag name: cache.context). See the documentation for more information https://www.drupal.org/docs/8/api/cache-api/cache-contexts, especially the warning about the Internal Page Cache in the last chapter concerning anonymous traffic. In most cases it should be a better option anyway to handle this edge side or even better client side in js, not server side.