Skip to main content

Disable cache for a block or a page in Drupal

Code snippet that can be used to disable caching for a block/ a page in Drupal

Disable cache for a block in Drupal

Cache max-age provides a declarative way to create time-dependent caches.

If you for example want to prevent a rendered block from being cached, you should specify max-age=0 on it.

Use $vars['#cache']['max-age'] = 0 to stop block being cache in drupal. 

/**
 * Implements hook_preprocess_HOOK()
 */
function mytheme_preprocess_block(&$vars) {
  if($vars['derivative_plugin_id'] == 'block-id-name') {
    $vars['#cache']['max-age'] = 0;
  }
}

for custom Block you can use getCacheMaxAge() method

class MyModuleBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
  }

  /**
   * @return int
   */
  public function getCacheMaxAge() {
    return 0;
  }
}

Also you can use \Drupal::service('page_cache_kill_switch')->trigger(); to disable the cache for anonymous users and all others too.

function fest_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
    if ($form_id == "node_something_form") {
        //disable the form cache for anonymous users and all others too
	      \Drupal::service('page_cache_kill_switch')->trigger();
	  }
}

Read about "Cache max-age"

Disable cache for a page in Drupal

Disable cache for a specific content type

<?php

use Drupal\node\NodeInterface;

/**
 * @param array $build
 * @param NodeInterface $node
 * @param $display
 * @param $view_mode
 */
function mymodule_node_view(array &$build, NodeInterface $node, $display, $view_mode) {
  $type = $node->getType();
  if ($type == 'article') {
    $build['#cache']['max-age'] = 0;
   \Drupal::service('page_cache_kill_switch')->trigger();
  }
}

Disable cache for a specific route

In a route of custom module my_company.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'

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

Example : 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(),
    ];
  }

}