How to condition output based on a URL query string In my node preprocess function I check the value of a query param...

$variables['exclude_urls'] = \Drupal::request()-&gt;get('exclude_urls');


And in my template, I have...

{% if not exclude_urls %}
  &lt;div class="gr-url"&gt;{{ url }}&lt;/div&gt;
{% endif %}


However, this approach doesn't work because the node preprocess function does not fire if nothing in the URL changes besides the value for the 'exclude_urls' param.

I have tried various methods to disable caching for the page.  Adding this to the route doesn't work...

  options:
    no_cache: 'TRUE'


I also tried using the page_cache_kill_switch in my controller, but it doesn't work...

\Drupal::service("page_cache_kill_switch")-&gt;trigger();


Neither does adding the query parameter to cache contexts...

$element['#cache']['contexts'][] = 'url.query_args:exclude_urls';


Instead of using hook_preprocess_node, is there some other way I should be checking the value of $_GET['exclude_urls'] and passing that to the template?  Do I add code to the twig template itself to check the value of 'exclude_urls'?  Is there any sure way to force hook_preprocess_node to fire every time?  What is the usual approach to conditioning display of content based on a URL query param so that caching won't interfere?

Update:  To be clear, I have also tried the above approaches in combination, with no success.  For example, the end of my page function in my controller looks like this...

\Drupal::service("page_cache_kill_switch")-&gt;trigger(); 
$element['#cache']['contexts'][] = 'url.query_args:exclude_urls';
return $element;


Update 2: In my local dev site, I do not experience this problem, and I've found that this line in my local settings makes it so hook_preprocess_node fires every time...

$settings['cache']['bins']['render'] = 'cache.backend.null';


However, I'm not sure how to take advantage of this in my production site, since I don't want to disable the render cache generally.  I can do something like this in settings.php, but it's a hack:

$parts = explode('?', $_SERVER['REQUEST_URI'], 2);
if ('/disable/cache/at/this/path' == $parts[0]) {
  $settings['cache']['bins']['render'] = 'cache.backend.null';
}
There are three layers where rendered content can be cached: 


The Page Cache, which stores complete pages based on the URL for anonymous users.
The Dynamic Page Cache, which stores pages with placeholders for dynamic content that is rendered on each request.
The Render Cache, which stores individual rendered elements.


Each has a corresponding cache bin that can be disabled during development in settings.php



To set an additional cache context in hook_preprocess, so that the Dynamic Page cache knows to re-render that fragment and the render cache stores variants as needed, update the #cache variable:

function hook_preprocess_HOOK(&amp;$variables) {
  $variables['#cache']['contexts'][] = 'url.query_args:exclude_urls';
}