Turn a WordPress Menu into a LiteSpeed ESI Block

by | Jan 7, 2020 | WordPress Tweaks

*** Post Updated 10/30/2022 to work with the latest LiteSpeed Cache for WordPress API *** 

LiteSpeed is growing in popularity and came in second as the web server of the year for 2021. It provides a powerful caching engine with a robust WordPress plugin that can greatly speed up any WordPress site. It’s Edge Side Includes (ESI) are particularly cutting edge, allowing you to “punch holes” in a publicly-cached page, and then fill those holes with privately-cached content.

Although it is rather straightforward to turn WordPress shortcodes into ESI blocks and there is a helpful interface for turning WordPress classic widgets into ESI bocks, it’s not quite so easy to turn a WordPress menu into a LiteSpeed ESI block.

Thankfully, with a little help from the LiteSpeed Wiki article on LSCache for WordPress API and a perusal of their ESI blocks code samples, I was able to create a simple function to fill this very need!

Let’s assume my WordPress theme is using the standard wp_nav_menu() function to insert a menu with the ID of “menu-id-to-replace” into a header template. The following code in your theme’s functions.php file would turn that menu into an ESI block, privately cached for each unique website visitor.

The basic logic goes like this: If WordPress is building a menu using wp_nav_menu (and it’s not building the ESI block), we use the wp_nav_menu() filter to override the normal output of the “menu-id-to-replace” menu and instead insert the contents of the “my-esi-menu” block.

If WordPress is building the “my-esi-menu” block, we insert the HTML code to display the menu.

As an example, I modified the above code to set the Astra theme’s secondary user navigation menu to be a LiteSpeed ESI block.


  1. Daniel

    Great article! Thank you!
    Could you please describe what the purpose would be to turn the WordPress Menu to LiteSpeed ESI, for us noobs? 😀
    Will it improve performance? What are the benefits?
    Thank you so much!

    • Robert Staddon

      Great question, Daniel! Turning the menu into an ESI block would allow it to display differently for different users on a cached page.

      For example, let’s say you wanted to use the popular “Nav Menu Roles” plugin (https://wordpress.org/plugins/nav-menu-roles/) to adjust the menu items that appear for various users based on their role. Unfortunately, once the page is cached on a site with LiteSpeed ESI enabled, the menu will appear the same for everyone even if they have different roles. However, by turning the menu into an ESI block, the page will remain cached but the menu will then be dynamically built for each user!

  2. Morshed Alam Suman


    I am not good at php. Can you help me on this?

    I use post views counter plugin by dFactory. In amp page I am using this code: do_shortcode(‘[post-views]’);

    As it is amp page, only php counter method works.

    I installed litespeed cache plugin and now post views is not updating. I just want this to be non cached.

    How can I do this?

  3. Usman

    Hi Robert,

    Is the bloew hook working for atest wordpress plugin and Latest lite speed plugin.

    add_action( ‘init’, function() {
    if ( method_exists( ‘LiteSpeed_Cache_API’, ‘esi_enabled’ ) && LiteSpeed_Cache_API::esi_enabled() ) {
    LiteSpeed_Cache_API::hook_tpl_not_esi( function () { …

    I used it 1 of my website but it didn’t work.

    Please advise


  4. Robert Staddon

    I’ve just updated the code in the post to work with the latest WordPress LiteSpeed plugin using their updated API

  5. Sean Bremner

    Thank you so much for this Robert! 🙂

    Would you recommend a similar approach to this for a Woocommerce Store, for turning the Cart into an ESI Block? And do you have any suggestions on how we could achieve that?

    P.S: I had to programmatically press the Submit Comment button to post this, because of the large “START” image that’s used in the Footer is preventing people from clicking on it.

    • Robert Staddon

      Thank you for reporting the “Submit Comment” button issue! It should be fixed now.

      LiteSpeed Cache seems to do a great job out of the box with the WooCommerce Store, automatically excluding My Account, Checkout, and Cart pages from caching. You can see a lot of this code in the /litespeed-cache/thirdparty/woocommerce.cls.php, woocommerce.content.tpl.php, and woocommerce.tab.tpl.php files. I don’t think that turning the Cart into an ESI Block is usually going to be needed.


Submit a Comment

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

Notify me of followup comments via e-mail. You can also subscribe without commenting.