27

I have activated the cache on my Drupal 8 site, and of course all pages are cached as expected.

However, I'd like to have a specific page bypass that cache.

In my controller I built the page as follows:

public function myPage() {
  return [
    '#markup' => time(),
  ];
}

How can I tell Drupal not to cache my page?

5 Answers 5

45

For Drupal 7

Drupal has the function drupal_page_is_cacheable() which can be used to set a page to uncacheable.

Here is the documentation: https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_page_is_cacheable/7

For Drupal 8

// Deny any page caching on the current request.    
\Drupal::service('page_cache_kill_switch')->trigger();

Then the code is:

public function myPage() {
  \Drupal::service('page_cache_kill_switch')->trigger();
  return [
    '#markup' => time(),
  ];
}

As usual, clean your cache once done.

Best practice (Drupal 8 | 9 | 10)

For performance and good practice reasons it is recommended to use dependency injection inside your Controller class.

modules/custom/my_module/MyController.php

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * A controller class that respects Drupal coding standards.
 *
 * @see https://www.drupal.org/docs/develop/standards
 */
class MyController extends ControllerBase {

  /**
   * Page cache kill switch.
   *
   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch
   */
  protected $killSwitch;

  /**
   * {@inheritdoc}
   */
  public function __construct(KillSwitch $kill_switch) {
    $this->killSwitch = $kill_switch;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('page_cache_kill_switch')
    );
  }

  /**
   * Render my page with a renderable array.
   *
   * @return array
   */
  public function myPage() : array {
    $this->killSwitch->trigger();
    return [
      '#markup' => time(),
    ];
  }

}

0
34

Disable cache for a specific page

Disable cache for a custom page from route declaration. If you want to disable cache for a custom controller (Custom module), You have no_cache option (YOUR_MODULE.routing.yml). Example : File : mymodule.routing.yml

mymodule.myroute:
  path: '/mymodule/mypage'
  defaults:
    _controller: '\Drupal\mymodule\Controller\Pages::mypage'
    _title: 'No cache page'
  requirements:
    _access: 'TRUE'
  options:
    no_cache: 'TRUE'

Added 'no_cache' route option to mark a route's responses as uncacheable

2
  • Prefer this answer as you are setting route specific access as well in this same location, plus it's cleaner.
    – Ron
    Commented May 20, 2020 at 17:08
  • The 'max-age' trick does not seem to work for rendering array returned by controllers in Drupal 9 anymore. But the options.no_cache still work. Commented May 16, 2022 at 8:34
16

In Drupal 8, you can mention cache as max-age till you want your page ouput to be cached. For removing cache of a particular page(Controller page), write 'max-age' => 0,.

public function myPage() {
  return [
   '#markup' => time(),
   '#cache' => ['max-age' => 0,],    //Set cache for 0 seconds.
  ];
} 
1
8

If you need to do something with a contrib module you can use a RouteSubscriber to fix the cache issue. you need a service ... or just run drupal gr if have drupal console.

 namespace Drupal\mymodule\Routing;

 use Drupal\Core\Routing\RouteSubscriberBase;
 use Symfony\Component\Routing\RouteCollection;

 class RouteSubscriber extends RouteSubscriberBase {

/**
 * {@inheritdoc}
 */
protected function alterRoutes(RouteCollection $collection) {
  // Find the route you need ...
  if ($route = $collection->get('some.contrib.route')) {
    $options = $route->getOptions();
    $options['no_cache'] = TRUE;
    $route->setOptions($options);
  }
 }
}

more info see https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones

0

You can use this module to avoid drupal cache and also server side cache like varnish https://www.drupal.org/project/ape

Its works for me in Varnish cache on acquia server.

1
  • Looks like this module is no longer maintained, so in case anyone comes here via google like I did, then the other answers should be explored.
    – Matt B
    Commented Sep 18, 2023 at 7:03

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.