cache-headers.php

I’ll build a strong performance/cache-headers.php file for your RX theme that adds cache-control, security-friendly headers, CDN/proxy support, static asset caching, HTML no-cache rules for logged-in users, and safe hooks for WordPress.

Below is an advanced rx-theme/inc/performance/cache-headers.php file for your RX Theme.

Create this file:

rx-theme/
└── inc/
    └── performance/
        └── cache-headers.php

Then include it from functions.php:

require_once get_template_directory() . '/inc/performance/cache-headers.php';

performance/cache-headers.php

<?php
/**
 * RX Theme - Advanced Performance Cache Headers
 *
 * File: inc/performance/cache-headers.php
 *
 * Purpose:
 * - Add browser cache headers
 * - Add CDN/proxy cache headers
 * - Add static asset cache rules
 * - Avoid caching admin, login, preview, REST write requests, WooCommerce cart/checkout
 * - Add ETag/Last-Modified helpers
 * - Add security-friendly performance headers
 * - Add resource hint support
 * - Add server-side output cache-control rules
 *
 * Important:
 * - PHP can only send headers before output starts.
 * - For best static asset caching, also configure .htaccess / Nginx / CDN.
 */

defined('ABSPATH') || exit;

if (!class_exists('RX_Theme_Cache_Headers')) :

final class RX_Theme_Cache_Headers {

    /**
     * Version for debugging and cache identification.
     */
    const VERSION = '1.0.0';

    /**
     * Default cache TTL values in seconds.
     */
    const TTL_HTML_PUBLIC       = 300;        // 5 minutes
    const TTL_HTML_SWR          = 600;        // 10 minutes stale-while-revalidate
    const TTL_HTML_SIE          = 86400;      // 1 day stale-if-error
    const TTL_FEED              = 1800;       // 30 minutes
    const TTL_REST_GET          = 300;        // 5 minutes
    const TTL_STATIC_SHORT      = 86400;      // 1 day
    const TTL_STATIC_MEDIUM     = 604800;     // 7 days
    const TTL_STATIC_LONG       = 31536000;   // 1 year
    const TTL_SITEMAP           = 3600;       // 1 hour
    const TTL_ROBOTS            = 86400;      // 1 day

    /**
     * Start hooks.
     */
    public static function init() {
        add_action('send_headers', array(__CLASS__, 'send_dynamic_cache_headers'), 1);
        add_action('template_redirect', array(__CLASS__, 'maybe_send_conditional_headers'), 0);
        add_filter('wp_headers', array(__CLASS__, 'filter_wp_headers'), 10, 2);
        add_filter('nocache_headers', array(__CLASS__, 'filter_nocache_headers'), 10, 1);
        add_filter('mod_rewrite_rules', array(__CLASS__, 'add_htaccess_cache_rules'));
        add_filter('robots_txt', array(__CLASS__, 'robots_txt_cache_note'), 10, 2);
        add_filter('wp_resource_hints', array(__CLASS__, 'resource_hints'), 10, 2);

        add_action('wp_head', array(__CLASS__, 'add_dns_prefetch_meta'), 1);
        add_action('wp_head', array(__CLASS__, 'add_cache_debug_meta'), 2);

        add_action('init', array(__CLASS__, 'maybe_handle_static_asset_request'), 0);
    }

    /**
     * Main dynamic header manager.
     */
    public static function send_dynamic_cache_headers() {
        if (headers_sent()) {
            return;
        }

        if (self::is_cache_bypass_request()) {
            self::send_no_store_headers('bypass-request');
            return;
        }

        if (self::is_admin_like_request()) {
            self::send_no_store_headers('admin-like-request');
            return;
        }

        if (self::is_user_specific_request()) {
            self::send_private_no_cache_headers('user-specific-request');
            return;
        }

        if (self::is_sensitive_ecommerce_request()) {
            self::send_no_store_headers('sensitive-ecommerce-request');
            return;
        }

        if (is_robots()) {
            self::send_public_cache_headers(self::TTL_ROBOTS, self::TTL_ROBOTS, self::TTL_ROBOTS, 'robots');
            return;
        }

        if (self::is_sitemap_request()) {
            self::send_public_cache_headers(self::TTL_SITEMAP, self::TTL_SITEMAP, self::TTL_SITEMAP, 'sitemap');
            return;
        }

        if (is_feed()) {
            self::send_public_cache_headers(self::TTL_FEED, self::TTL_FEED, self::TTL_HTML_SIE, 'feed');
            return;
        }

        if (self::is_rest_get_request()) {
            self::send_public_cache_headers(self::TTL_REST_GET, self::TTL_REST_GET, self::TTL_HTML_SIE, 'rest-get');
            return;
        }

        if (is_404() || is_search()) {
            self::send_private_no_cache_headers('search-or-404');
            return;
        }

        if (is_front_page() || is_home() || is_singular() || is_archive() || is_page()) {
            self::send_public_cache_headers(
                self::TTL_HTML_PUBLIC,
                self::TTL_HTML_SWR,
                self::TTL_HTML_SIE,
                'html-public'
            );

            self::send_last_modified_for_wp_query();
            return;
        }

        self::send_public_cache_headers(
            self::TTL_HTML_PUBLIC,
            self::TTL_HTML_SWR,
            self::TTL_HTML_SIE,
            'html-default'
        );
    }

    /**
     * Modify WordPress headers before output.
     */
    public static function filter_wp_headers($headers, $wp) {
        if (!is_array($headers)) {
            $headers = array();
        }

        $headers['X-RX-Theme-Cache'] = 'enabled';
        $headers['X-RX-Cache-Version'] = self::VERSION;

        if (!isset($headers['X-Content-Type-Options'])) {
            $headers['X-Content-Type-Options'] = 'nosniff';
        }

        if (!isset($headers['Referrer-Policy'])) {
            $headers['Referrer-Policy'] = 'strict-origin-when-cross-origin';
        }

        if (!isset($headers['X-Frame-Options']) && !self::is_customize_preview_safe()) {
            $headers['X-Frame-Options'] = 'SAMEORIGIN';
        }

        if (!isset($headers['Permissions-Policy'])) {
            $headers['Permissions-Policy'] = 'camera=(), microphone=(), geolocation=(), interest-cohort=()';
        }

        return $headers;
    }

    /**
     * Improve WordPress no-cache headers.
     */
    public static function filter_nocache_headers($headers) {
        if (!is_array($headers)) {
            $headers = array();
        }

        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0, private';
        $headers['Pragma']        = 'no-cache';
        $headers['Expires']       = 'Wed, 11 Jan 1984 05:00:00 GMT';
        $headers['X-RX-Cache']    = 'no-cache';

        return $headers;
    }

    /**
     * Public CDN/browser cache headers.
     */
    private static function send_public_cache_headers($max_age, $swr = 0, $sie = 0, $reason = 'public') {
        if (headers_sent()) {
            return;
        }

        $max_age = absint($max_age);
        $swr     = absint($swr);
        $sie     = absint($sie);

        $cache_control = array(
            'public',
            'max-age=' . $max_age,
        );

        if ($swr > 0) {
            $cache_control[] = 'stale-while-revalidate=' . $swr;
        }

        if ($sie > 0) {
            $cache_control[] = 'stale-if-error=' . $sie;
        }

        header('Cache-Control: ' . implode(', ', $cache_control), true);
        header('Surrogate-Control: max-age=' . $max_age, true);
        header('CDN-Cache-Control: public, max-age=' . $max_age, true);
        header('Cloudflare-CDN-Cache-Control: public, max-age=' . $max_age, true);
        header('X-RX-Cache: HIT-ELIGIBLE; reason=' . sanitize_key($reason), true);

        self::send_common_performance_headers();
    }

    /**
     * Private but not full no-store.
     */
    private static function send_private_no_cache_headers($reason = 'private') {
        if (headers_sent()) {
            return;
        }

        header('Cache-Control: private, no-cache, must-revalidate, max-age=0', true);
        header('Pragma: no-cache', true);
        header('Expires: Wed, 11 Jan 1984 05:00:00 GMT', true);
        header('X-RX-Cache: PRIVATE; reason=' . sanitize_key($reason), true);

        self::send_common_performance_headers();
    }

    /**
     * Strict no-store for admin, login, preview, cart, checkout, nonce pages.
     */
    private static function send_no_store_headers($reason = 'no-store') {
        if (headers_sent()) {
            return;
        }

        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, private', true);
        header('Pragma: no-cache', true);
        header('Expires: Wed, 11 Jan 1984 05:00:00 GMT', true);
        header('X-RX-Cache: BYPASS; reason=' . sanitize_key($reason), true);

        self::send_common_performance_headers();
    }

    /**
     * Common safe performance headers.
     */
    private static function send_common_performance_headers() {
        if (headers_sent()) {
            return;
        }

        header('X-Content-Type-Options: nosniff', false);
        header('Referrer-Policy: strict-origin-when-cross-origin', false);
        header('Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()', false);
        header('X-RX-Theme: cache-headers', false);

        if (!self::is_customize_preview_safe()) {
            header('X-Frame-Options: SAMEORIGIN', false);
        }

        if (is_ssl()) {
            header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload', false);
        }
    }

    /**
     * Send Last-Modified header based on queried posts.
     */
    private static function send_last_modified_for_wp_query() {
        if (headers_sent()) {
            return;
        }

        global $wp_query;

        if (empty($wp_query) || empty($wp_query->posts) || !is_array($wp_query->posts)) {
            return;
        }

        $last_modified = 0;

        foreach ($wp_query->posts as $post) {
            if (!empty($post->post_modified_gmt)) {
                $modified = strtotime($post->post_modified_gmt . ' GMT');
                if ($modified > $last_modified) {
                    $last_modified = $modified;
                }
            }
        }

        if ($last_modified > 0) {
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT', true);

            $etag = '"' . md5(home_url(add_query_arg(array(), $_SERVER['REQUEST_URI'] ?? '')) . '|' . $last_modified . '|' . self::VERSION) . '"';
            header('ETag: ' . $etag, true);
        }
    }

    /**
     * Conditional 304 support.
     */
    public static function maybe_send_conditional_headers() {
        if (headers_sent()) {
            return;
        }

        if (self::is_cache_bypass_request() || is_user_logged_in()) {
            return;
        }

        global $wp_query;

        if (empty($wp_query) || empty($wp_query->posts) || !is_array($wp_query->posts)) {
            return;
        }

        $last_modified = 0;

        foreach ($wp_query->posts as $post) {
            if (!empty($post->post_modified_gmt)) {
                $modified = strtotime($post->post_modified_gmt . ' GMT');
                if ($modified > $last_modified) {
                    $last_modified = $modified;
                }
            }
        }

        if ($last_modified <= 0) {
            return;
        }

        $etag = '"' . md5(home_url(add_query_arg(array(), $_SERVER['REQUEST_URI'] ?? '')) . '|' . $last_modified . '|' . self::VERSION) . '"';

        $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
            ? strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']))
            : false;

        $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH'])
            ? trim(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']))
            : false;

        $etag_match = $if_none_match && $if_none_match === $etag;
        $time_match = $if_modified_since && $if_modified_since >= $last_modified;

        if ($etag_match || $time_match) {
            status_header(304);
            header('ETag: ' . $etag, true);
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT', true);
            header('Cache-Control: public, max-age=' . self::TTL_HTML_PUBLIC . ', stale-while-revalidate=' . self::TTL_HTML_SWR, true);
            exit;
        }
    }

    /**
     * Detect request types that must bypass cache.
     */
    private static function is_cache_bypass_request() {
        if (defined('DONOTCACHEPAGE') && DONOTCACHEPAGE) {
            return true;
        }

        if (defined('REST_REQUEST') && REST_REQUEST && !self::is_rest_get_request()) {
            return true;
        }

        if (is_preview() || is_customize_preview()) {
            return true;
        }

        if (self::request_has_query_bypass()) {
            return true;
        }

        if (self::request_method_is_unsafe()) {
            return true;
        }

        if (self::has_auth_cookies()) {
            return true;
        }

        return false;
    }

    /**
     * Admin/login/ajax/customizer pages.
     */
    private static function is_admin_like_request() {
        if (is_admin()) {
            return true;
        }

        if (wp_doing_ajax()) {
            return true;
        }

        if (wp_doing_cron()) {
            return true;
        }

        $uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';

        $admin_paths = array(
            '/wp-admin',
            '/wp-login.php',
            '/wp-register.php',
            '/xmlrpc.php',
            '/wp-json/wp/v2/users/me',
        );

        foreach ($admin_paths as $path) {
            if (stripos($uri, $path) !== false) {
                return true;
            }
        }

        return false;
    }

    /**
     * Logged-in or personalized pages.
     */
    private static function is_user_specific_request() {
        if (is_user_logged_in()) {
            return true;
        }

        if (is_author()) {
            return false;
        }

        $cookies = array_keys($_COOKIE);

        $private_cookie_patterns = array(
            'wordpress_logged_in_',
            'wp-postpass_',
            'comment_author_',
            'woocommerce_items_in_cart',
            'woocommerce_cart_hash',
            'wp_woocommerce_session_',
            'edd_items_in_cart',
            'rx_private_',
        );

        foreach ($cookies as $cookie_name) {
            foreach ($private_cookie_patterns as $pattern) {
                if (stripos($cookie_name, $pattern) === 0 || stripos($cookie_name, $pattern) !== false) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * WooCommerce / Easy Digital Downloads sensitive pages.
     */
    private static function is_sensitive_ecommerce_request() {
        if (function_exists('is_cart') && is_cart()) {
            return true;
        }

        if (function_exists('is_checkout') && is_checkout()) {
            return true;
        }

        if (function_exists('is_account_page') && is_account_page()) {
            return true;
        }

        if (function_exists('edd_is_checkout') && edd_is_checkout()) {
            return true;
        }

        if (function_exists('edd_is_success_page') && edd_is_success_page()) {
            return true;
        }

        if (function_exists('edd_is_failed_transaction_page') && edd_is_failed_transaction_page()) {
            return true;
        }

        return false;
    }

    /**
     * REST GET can be cached briefly.
     */
    private static function is_rest_get_request() {
        if (!(defined('REST_REQUEST') && REST_REQUEST)) {
            return false;
        }

        $method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper(sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD']))) : 'GET';

        return $method === 'GET';
    }

    /**
     * Unsafe methods should never be cached.
     */
    private static function request_method_is_unsafe() {
        $method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper(sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD']))) : 'GET';

        return in_array($method, array('POST', 'PUT', 'PATCH', 'DELETE'), true);
    }

    /**
     * Cache bypass query strings.
     */
    private static function request_has_query_bypass() {
        $bypass_keys = array(
            'preview',
            'customize_changeset_uuid',
            'customize_theme',
            'doing_wp_cron',
            'nocache',
            'no_cache',
            'cache_bypass',
            'elementor-preview',
            'bricks',
            'oxygen_iframe',
            'fl_builder',
            'et_fb',
            'vc_editable',
            'rx_no_cache',
        );

        foreach ($bypass_keys as $key) {
            if (isset($_GET[$key])) {
                return true;
            }
        }

        return false;
    }

    /**
     * Authentication cookies.
     */
    private static function has_auth_cookies() {
        if (empty($_COOKIE) || !is_array($_COOKIE)) {
            return false;
        }

        foreach (array_keys($_COOKIE) as $cookie_name) {
            if (
                stripos($cookie_name, 'wordpress_logged_in_') !== false ||
                stripos($cookie_name, 'wordpress_sec_') !== false ||
                stripos($cookie_name, 'wp-settings-') !== false
            ) {
                return true;
            }
        }

        return false;
    }

    /**
     * Detect sitemap.
     */
    private static function is_sitemap_request() {
        $uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';

        if (stripos($uri, 'sitemap') !== false && preg_match('/\.xml(\.gz)?($|\?)/i', $uri)) {
            return true;
        }

        if (function_exists('wp_sitemaps_get_server') && get_query_var('sitemap')) {
            return true;
        }

        return false;
    }

    /**
     * Customizer needs frame access.
     */
    private static function is_customize_preview_safe() {
        return is_customize_preview() || isset($_GET['customize_changeset_uuid']);
    }

    /**
     * Handle direct static asset requests if PHP receives them.
     *
     * Usually Apache/Nginx/CDN handles static files before PHP.
     * This is useful for custom routing or PHP-served assets.
     */
    public static function maybe_handle_static_asset_request() {
        if (headers_sent()) {
            return;
        }

        $uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';

        if (!$uri) {
            return;
        }

        $path = parse_url($uri, PHP_URL_PATH);
        $ext  = strtolower(pathinfo($path, PATHINFO_EXTENSION));

        if (!$ext) {
            return;
        }

        $long_cache = array(
            'css',
            'js',
            'mjs',
            'json',
            'map',
            'jpg',
            'jpeg',
            'png',
            'gif',
            'webp',
            'avif',
            'svg',
            'ico',
            'woff',
            'woff2',
            'ttf',
            'otf',
            'eot',
            'mp4',
            'webm',
            'ogg',
            'mp3',
            'wav',
            'pdf',
        );

        if (!in_array($ext, $long_cache, true)) {
            return;
        }

        $ttl = self::TTL_STATIC_LONG;

        if (in_array($ext, array('json', 'map'), true)) {
            $ttl = self::TTL_STATIC_MEDIUM;
        }

        if (in_array($ext, array('html', 'xml'), true)) {
            $ttl = self::TTL_STATIC_SHORT;
        }

        header('Cache-Control: public, max-age=' . $ttl . ', immutable', true);
        header('CDN-Cache-Control: public, max-age=' . $ttl, true);
        header('X-RX-Static-Cache: enabled; ext=' . sanitize_key($ext), true);

        self::send_static_content_type_header($ext);
        self::send_common_performance_headers();
    }

    /**
     * Static asset content type helper.
     */
    private static function send_static_content_type_header($ext) {
        $types = array(
            'css'   => 'text/css; charset=UTF-8',
            'js'    => 'application/javascript; charset=UTF-8',
            'mjs'   => 'application/javascript; charset=UTF-8',
            'json'  => 'application/json; charset=UTF-8',
            'map'   => 'application/json; charset=UTF-8',
            'svg'   => 'image/svg+xml; charset=UTF-8',
            'webp'  => 'image/webp',
            'avif'  => 'image/avif',
            'png'   => 'image/png',
            'jpg'   => 'image/jpeg',
            'jpeg'  => 'image/jpeg',
            'gif'   => 'image/gif',
            'ico'   => 'image/x-icon',
            'woff'  => 'font/woff',
            'woff2' => 'font/woff2',
            'ttf'   => 'font/ttf',
            'otf'   => 'font/otf',
            'eot'   => 'application/vnd.ms-fontobject',
            'pdf'   => 'application/pdf',
            'mp4'   => 'video/mp4',
            'webm'  => 'video/webm',
            'ogg'   => 'audio/ogg',
            'mp3'   => 'audio/mpeg',
            'wav'   => 'audio/wav',
        );

        if (isset($types[$ext])) {
            header('Content-Type: ' . $types[$ext], false);
        }
    }

    /**
     * Resource hints: dns-prefetch / preconnect.
     */
    public static function resource_hints($urls, $relation_type) {
        if (!is_array($urls)) {
            $urls = array();
        }

        $dns_prefetch = array(
            '//fonts.googleapis.com',
            '//fonts.gstatic.com',
            '//www.googletagmanager.com',
            '//www.google-analytics.com',
            '//cdn.jsdelivr.net',
            '//cdnjs.cloudflare.com',
            '//unpkg.com',
        );

        $preconnect = array(
            'https://fonts.gstatic.com',
            'https://fonts.googleapis.com',
        );

        if ('dns-prefetch' === $relation_type) {
            $urls = array_merge($urls, $dns_prefetch);
        }

        if ('preconnect' === $relation_type) {
            $urls = array_merge($urls, $preconnect);
        }

        return array_values(array_unique($urls));
    }

    /**
     * Extra DNS meta output.
     */
    public static function add_dns_prefetch_meta() {
        if (is_admin()) {
            return;
        }

        echo "\n<!-- RX Theme Performance Resource Hints -->\n";
        echo '<link rel="dns-prefetch" href="//fonts.googleapis.com">' . "\n";
        echo '<link rel="dns-prefetch" href="//fonts.gstatic.com">' . "\n";
        echo '<link rel="dns-prefetch" href="//www.googletagmanager.com">' . "\n";
        echo '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . "\n";
    }

    /**
     * Optional debug meta.
     */
    public static function add_cache_debug_meta() {
        if (!defined('WP_DEBUG') || !WP_DEBUG) {
            return;
        }

        if (is_admin()) {
            return;
        }

        echo "\n" . '<meta name="rx-cache-headers" content="enabled; version=' . esc_attr(self::VERSION) . '">' . "\n";
    }

    /**
     * Add .htaccess rules when WordPress regenerates rewrite rules.
     *
     * Important:
     * This only works on Apache with mod_rewrite and mod_expires/mod_headers enabled.
     */
    public static function add_htaccess_cache_rules($rules) {
        $rx_rules = self::get_apache_cache_rules();

        if (strpos($rules, '# BEGIN RX Theme Cache Headers') !== false) {
            return $rules;
        }

        return $rx_rules . "\n\n" . $rules;
    }

    /**
     * Apache cache rules text.
     */
    private static function get_apache_cache_rules() {
        return <<<HTACCESS
# BEGIN RX Theme Cache Headers

<IfModule mod_expires.c>
    ExpiresActive On

    # Images
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/avif "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"

    # Fonts
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 year"

    # CSS and JavaScript
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"
    ExpiresByType application/x-javascript "access plus 1 year"

    # Media
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType video/webm "access plus 1 year"
    ExpiresByType audio/mpeg "access plus 1 year"
    ExpiresByType audio/ogg "access plus 1 year"
    ExpiresByType audio/wav "access plus 1 year"

    # Documents
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType application/json "access plus 7 days"
    ExpiresByType application/xml "access plus 1 hour"
    ExpiresByType text/xml "access plus 1 hour"
</IfModule>

<IfModule mod_headers.c>
    <FilesMatch "\\.(css|js|mjs|jpg|jpeg|png|gif|webp|avif|svg|ico|woff|woff2|ttf|otf|eot|mp4|webm|ogg|mp3|wav)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
        Header unset Pragma
        Header unset ETag
    </FilesMatch>

    <FilesMatch "\\.(json|map)$">
        Header set Cache-Control "public, max-age=604800"
    </FilesMatch>

    <FilesMatch "\\.(xml|txt)$">
        Header set Cache-Control "public, max-age=3600"
    </FilesMatch>

    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"

    <IfModule mod_setenvif.c>
        SetEnvIfNoCase Request_URI "\\.(?:gif|jpe?g|png|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|ogg|mp3|wav)$" RX_STATIC_ASSET
        Header set X-RX-Static-Cache "apache" env=RX_STATIC_ASSET
    </IfModule>
</IfModule>

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>

<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/plain
    AddOutputFilterByType BROTLI_COMPRESS text/html
    AddOutputFilterByType BROTLI_COMPRESS text/xml
    AddOutputFilterByType BROTLI_COMPRESS text/css
    AddOutputFilterByType BROTLI_COMPRESS text/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/json
    AddOutputFilterByType BROTLI_COMPRESS application/xml
    AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>

FileETag None

# END RX Theme Cache Headers
HTACCESS;
    }

    /**
     * Add useful note in robots.txt.
     */
    public static function robots_txt_cache_note($output, $public) {
        $output .= "\n# RX Theme cache headers enabled\n";
        return $output;
    }
}

RX_Theme_Cache_Headers::init();

endif;

Best functions.php include code

Add this in your RX theme functions.php:

/**
 * RX Theme Performance Files
 */
$rx_cache_headers_file = get_template_directory() . '/inc/performance/cache-headers.php';

if (file_exists($rx_cache_headers_file)) {
    require_once $rx_cache_headers_file;
}

Important note

This file is safe for dynamic WordPress pages because it avoids full public cache for logged-in users, admin pages, preview pages, cart/checkout pages, POST requests, AJAX, REST write requests, and private-cookie pages.

For the strongest result, combine it with:

Cloudflare Cache Rules
LiteSpeed Cache / Hostinger Cache
Apache .htaccess cache headers
Optimized enqueue.php
preload.php
dns-prefetch/preconnect
Critical CSS
defer/async JavaScript
WebP/AVIF images

This file is a strong base for your RX Theme performance system.

Leave a Reply

Your email address will not be published. Required fields are marked *