How to preserve facet selections across pages
FacetWP automatically generates a permalink URL whenever you interact with facets. This allows you to bookmark the page with the facets in place.
However, when navigating to other pages on your site, the facet selections are lost. Fortunately, it’s possible to preserve the facets’ state across pages, by using cookies.
Preserve facet selections for a single facet page
The following code preserves facet choices of a specific page in a cookie, and upon returning to the page, it will reload the page with the facet choices stored in the cookie.
Note that the code below is meant to work for only one page with facets. If you have multiple facet pages, the reloading of the facet choices stored in the cookie would happen on all pages with facets, not only the one on which the choices were made. To prevent this, we wrapped the whole function in a condition that checks the URI of the page with FWP_HTTP.uri (on line 9). (The URI is the part of the page URL that comes after the domain name, without a / at the beginning or end.)
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
add_action( 'wp_head', function() { ?> <script> (function($) { $(function() { // Optionally use the code only on a specific page, by checking the page URI // Only needed if you have multiple pages with facets if ('my/facetpage_uri' == FWP_HTTP.uri) { // Replace 'my/facetpage_uri' with your page URI (the part of the page URL after the domain name, without a / at the beginning or end) // Cookie handler function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } // Each time FacetWP refreshes (after using facets), store facet selections into a cookie $(document).on('facetwp-loaded', function() { var date = new Date(); var facets = window.location.search; date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); document.cookie = "facetdata=" + facets + "; expires=" + date.toGMTString() + "; path=/"; // Set the cookie }); // When FacetWP first initializes (on first page load), look for the "facetdata" cookie // If it exists, clear the cookie, and set window.location.search = facetdata $(document).on('facetwp-refresh', function() { if (!FWP.loaded) { // On first page load only var facets = window.location.search; var facetdata = readCookie('facetdata'); // Read facet selections from the cookie if (null != facetdata && '' == facets && '' != facetdata && facets != facetdata) { document.cookie = 'facetdata=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'; // Clear the cookie window.location.search = facetdata; // Set facet selections from cookie } } }); } // end URI check }); })(jQuery); </script> <?php }, 100 );
Preserve facet selections across multiple facet pages
You may want to preserve facet selections across multiple pages of a site, all with facets. If these pages all have the same set of facets, and all of them need to show the preserved selections when loaded, you can use the above code and remove the URI check in line 9 and 44.
If your facet pages are not sharing the exact same set of facets, or if you need more control over where the cookie is set and retrieved, you can use the ingredients in the code below.
First, you need to decide on which page(s) the cookie is stored. To do this, you can use a check for the page URI. In lines 63-73 of the code below, the cookie is stored after using facets on the page with URI my/facetpage. (The URI is the part of the page URL that comes after the domain name, without a / at the beginning or end.)
In lines 79-89, the selections from the cookie are retrieved on any page with facets, as there is no check for the URI. There could be scenarios in which you want to use the selections from the cookie only on specific pages. In which case you could add an extra URI check around the whole retrieval part.
In line 84, the cookie is cleared after using it to set the facet selections, when visiting any facet page for the first time. If you want the clearing to happen only on the page where the cookie was set, you could add an extra URI check around line 84.
Not all of your facet pages may have the exact same set of facets. The page where the cookie is set may have facets a, b and c, while a page where the cookie is retrieved, may only have facets a and b. The code below accounts for that by filtering the facet selections retrieved from the cookie by the actual facets that are on the page. The filterFacetURL() function that does this runs in line 85, just before setting the selections from the cookie. This prevents issues with facet selections being loaded for non-existent facets.
The code has one more (optional) feature: in lines 92-94, the cookie is cleared after using a Reset facet. Removed these lines if you don’t want that.
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
add_action( 'wp_head', function() { ?> <script> (function($) { $(function() { // Cookie handler function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } // Removes URL query parameters from a facet string if their (unprefixed) keys // do not exist as keys in the FWP.facets object function filterFacetURL(facetdata) { if (!facetdata || facetdata.length <= 1) { // Handle empty or just '?' string return ''; } if (typeof FWP === 'undefined' || typeof FWP.facets === 'undefined') { return facetdata; // Return original if FWP.facets is missing } // Get an array of valid facet names from FWP.facets const validFacetNamesWithoutPrefix = Object.keys(FWP.facets); // Remove the leading '?' if it exists, then split into individual key-value pairs const queryString = facetdata.startsWith('?') ? facetdata.substring(1) : facetdata; const params = queryString.split('&'); const validParams = []; const prefix = FWP_JSON.prefix; params.forEach(param => { const parts = param.split('='); const urlKey = parts[0]; // This is the facet name from URL (e.g., "_range_list") // Remove the prefix for comparison with FWP.facets keys const unprefixedKey = urlKey.startsWith(prefix) ? urlKey.substring(1) : urlKey; // Check if this unprefixed key exists in our list of active facets from FWP.facets if (validFacetNamesWithoutPrefix.includes(unprefixedKey)) { validParams.push(param); // If it's a valid facet, keep the full param string } }); // Reconstruct the query string with only the valid parameters if (validParams.length > 0) { return '?' + validParams.join('&'); } else { return ''; // No valid facets found } } // Store the cookie only on this facet page. if ('my/facetpage_uri' == FWP_HTTP.uri) { // Replace 'my/facetpage_uri' with your page URI (the part of the page URL after the domain name, without a / at the beginning or end) // Each time FacetWP refreshes (after using facets), store facet selections into a cookie $(document).on('facetwp-loaded', function() { var date = new Date(); var facets = window.location.search; date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); document.cookie = "facetdata=" + facets + "; expires=" + date.toGMTString() + "; path=/"; // Set the cookie }); } // Use, then clear the cookie on any facet page // When FacetWP first initializes (on first page load), look for the "facetdata" cookie // If it exists, clear the cookie // Then sync the data with the facets existing on the page, and set window.location.search = facetdata $(document).on('facetwp-refresh', function() { if (!FWP.loaded) { // On first page load only var facets = window.location.search; var facetdata = readCookie('facetdata'); // Read facet selections from the cookie if (null != facetdata && '' == facets && '' != facetdata && facets != facetdata) { document.cookie = 'facetdata=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'; // Clear the cookie facetdata = filterFacetURL(facetdata); // Sync data with existing facets window.location.search = facetdata; // Set facet selections from cookie } } }); // Optional: Clear cookie on reset (when using a Reset facet) FWP.hooks.addAction('facetwp/reset', function() { document.cookie = 'facetdata=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'; // Clear the cookie }); }); })(jQuery); </script> <?php }, 100 );
