Developer Advisory – Experimental Feature: Clearing of Empty Sessions in WooCommerce 10.3

WooCommerce 10.3 introduces experimental session management changes designed to improve site performance through better caching compatibility. These changes, centered around the new Clear Customer Sessions When Empty feature, automatically remove unnecessary session cookies that prevent effective page caching for non-logged-in users.

Checkbox option for 'Clear Customer Sessions When Empty' setting in WooCommerce, with a description explaining its impact on performance and potential compatibility issues.

The feature operates during the template_redirect action and will remove the session from the server and the session cookie from the client enabling improved cache hit rates for guests browsing a site with empty carts. This feature applies the following careful guards:

  1. Feature Gate: Only runs when experimentally enabled.
  2. User Check: Skips logged-in users who already bypass output caching due to the WordPress cookie.
  3. Session Validation: Only destroys sessions when both cart and session data are empty.
  4. Compatibility: Runs late in the request cycle (priority 999) to give every opportunity for extensions to populate session data, if needed.

WooCommerce has also implemented session cleanup improvements across core to remove any session data once it is no longer needed allowing guests to return to cached pages sooner.

  • Avoid storing customer information in session when it is just the default data. (PR #60852)
  • Cleanup shipping data from session after cart is destroyed. (PR #60800)
  • Cleanup store_api_draft_order from session. (PR #60739)

This feature is currently available as an experimental option and is disabled by default. Manual activation is required for testing. Pending community feedback and compatibility validation, this may become the default behavior in future WooCommerce releases.

How can developers tell if they are affected?

This feature will affect you if your extension:

  • Initializes sessions for features that might not require server-side persistence, e.g. WC()->session->set_customer_session_cookie( true ) to bypass output caching without actually storing session data.
  • Stores data in sessions without proper cleanup when no longer needed, causing the session to persist longer than necessary.

A common pattern that will be affected is extensions that call WC()->session->set_customer_session_cookie( true ) solely to bypass caching for certain pages or functionality, without actually storing any data in the session. Examples include:

  • Extensions that need dynamic content but don’t require server-side data persistence
  • Plugins that use session cookies just to ensure users receive personalized nonces
  • Features that initialize session cookies for user identification without storing session data
  • Functionality that bypasses caching for A/B testing or personalization without session storage

What action do developers need to take if affected?

For Extensions Using Session Cookies for Cache Bypassing

If your extension calls WC()->session->set_customer_session_cookie( true ) without storing session data or your extension does need to store some user specific transient data, you have several alternatives:

Option 1: Use custom REST endpoint to asynchronously load custom content.

// Register custom REST endpoint
add_action('rest_api_init', function() {
    register_rest_route('my-plugin/v1', '/dynamic-content/', [
        'methods' => 'GET',
        'callback' => 'get_dynamic_content_callback',
        'permission_callback' => '__return_true'
    ]);
});
// JavaScript to fetch via REST API
fetch('/wp-json/my-plugin/v1/dynamic-content/')
    .then(response => response.json())
    .then(data => {
        document.getElementById('dynamic-content').innerHTML = data.content;
    });

Option 2: Use alternative cache-bypassing methods.

// Use custom cookies instead of session cookies to identify a unique guest.
setcookie( 'my_extension_nocache', '<unique_identifier>', time() + 3600, '/' );
// Prevent caching for the specific request that needs that unique identifier.
add_filter( 'any_action_before_output_is_sent', function() {
    if ( my_extension_needs_dynamic_content() ) {
        nocache_headers();
        if (!defined('DONOTCACHEPAGE')) {
            // Used by some caching plugins.
            define('DONOTCACHEPAGE', true);
        }
    }
});

Because the page above is uncached, your extension will have access to this custom cookie from the guest user, but the cookie itself will not cause cache to be bypassed for all requests as long as it doesn’t start with wp_

Option 3: Use client side localStorage/sessionStorage.

// Store user preferences client-side
localStorage.setItem('user_preference', 'value');
// Check and use stored data
if (localStorage.getItem('popup_shown') !== 'true') {
    showPopup();
    localStorage.setItem('popup_shown', 'true');
}
// Session-specific storage
sessionStorage.setItem('current_session_data', JSON.stringify(data));

Option 4: Use sessions, but with proper cleanup:

// Clean up when feature is complete
WC()->session->set('temporary_data', null);
// Use appropriate cleanup hooks
add_action('woocommerce_cart_emptied', function() {
    WC()->session->set('my_cart_related_data', null);
});

Leave a Reply

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