You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We are experiencing an issue with our application using the useInfiniteHits hook from Algolia's React InstantSearch library. When a user navigates from a Product Listing Page (PLP) to a Product Detail Page (PDP) and then uses the browser's back button to return to the PLP, the search state resets, and all product hits are cleared (the user has to click on "Load more" again).
What We Have Tried
Algolia's In-Memory Cache
According to the Algolia documentation, an in-memory cache is used to persist product hits and search state. However, this does not seem to persist across navigations using the browser's back button.
Custom Cache Implementation
We implemented a custom cache object that reads from and writes to sessionStorage to track product hits and search state. This approach partially works:
On the first navigation back from the PDP to the PLP, the search state and product hits are correctly persisted.
On subsequent navigations, the cache seems to clear, and the state resets again.
Relevant Code Components
The following code has been simplified to keep only relevant parts of the current implementation and to provide a general overview.
InstantSearchWrapper Component
This component initializes the search client, sets up the initial UI state, and configures Algolia for search operations.
We are aware of the react-instantsearch-router-nextjs library, which handles URL-based routing for state persistence. However, integrating this is not an option for us because we have custom routing logic that would be overwritten by allowing InstantSearch to control the URL.
We confirmed that the Algolia client is created only once and is not being reinitialized during navigation, ruling out client recreation as the cause.
Environment
next: ^12.1.6
react: 18.0.0
react-dom: 18.0.0
Any insights or recommended approaches would be greatly appreciated.
🔍 Steps to reproduce
Steps to Reproduce:
User lands on the PLP and performs a search.
User clicks on a product to navigate to the PDP.
User clicks the browser back button to return to the PLP.
Upon returning to the PLP, the search state and product hits are reset.
Live reproduction
none
💭 Expected behavior
Expected Behavior:
The search state and product hits should be persisted when navigating back from the PDP to the PLP, ensuring a seamless user experience without re-fetching data.
@enmanuelramirez-ad We have the same problem, it seems on the first render with data from a server component disjunctiveFacets & disjunctiveFacetsRefinements are missing in the state.
So the compare fails and the cache is resetten on back, the same is happening on dirst render.
So we have 2 workarounds, in the cache read function.
This is not the best piece of code but it works for us for now :)
import { isEqual } from 'instantsearch.js/es/lib/utils/isEqual';
const getStateWithoutPage = (state) => {
const { page, ...rest } = state || {};
return rest;
}
const isServer = typeof window === 'undefined';
// Work around for Nextjs, disjunctiveFacets & disjunctiveFacetsRefinements are missing from state, this triggers a emty hits array
const infiniteHitsCache = (() => {
let cache = null;
return {
read: ({ state }) => {
if (cache === null || isServer) {
return null;
}
// Fix first render reset hits
if (cache.first) {
cache = {
...cache,
first: false,
state: {
...cache.state,
disjunctiveFacets: state.disjunctiveFacets,
disjunctiveFacetsRefinements: state.disjunctiveFacetsRefinements
}
}
}
// Fix on back reset hits
if (state.disjunctiveFacets.length === 0) {
state = {
...state,
disjunctiveFacets: cache.state.disjunctiveFacets,
disjunctiveFacetsRefinements: cache.state.disjunctiveFacetsRefinements
}
}
return cache && isEqual(getStateWithoutPage(cache.state), getStateWithoutPage(state)) ? cache.hits : null;
},
write: ({ state, hits }) => {
cache = {
first: (state.disjunctiveFacets.length === 0),
state: state,
hits: hits
}
},
};
})();
export default infiniteHitsCache;
🐛 Current behavior
Issue Summary
We are experiencing an issue with our application using the useInfiniteHits hook from Algolia's React InstantSearch library. When a user navigates from a Product Listing Page (PLP) to a Product Detail Page (PDP) and then uses the browser's back button to return to the PLP, the search state resets, and all product hits are cleared (the user has to click on "Load more" again).
What We Have Tried
Algolia's In-Memory Cache
Custom Cache Implementation
sessionStorage
to track product hits and search state. This approach partially works:Relevant Code Components
The following code has been simplified to keep only relevant parts of the current implementation and to provide a general overview.
InstantSearchWrapper Component
This component initializes the search client, sets up the initial UI state, and configures Algolia for search operations.
SearchQueryRenderer Component
This component dynamically generates configurations and manages the search query state.
SearchQuery Component
This component manages the search query state and utilizes
useInfiniteHits
to fetch product hits.Additional Information
Environment
^12.1.6
18.0.0
18.0.0
Any insights or recommended approaches would be greatly appreciated.
🔍 Steps to reproduce
Steps to Reproduce:
Live reproduction
none
💭 Expected behavior
Expected Behavior:
The search state and product hits should be persisted when navigating back from the PDP to the PLP, ensuring a seamless user experience without re-fetching data.
Package version
react-instantsearch-core: ^7.1.0, algoliasearch: ^4.20.0, instantsearch.js: ^4.63.0
Operating system
macOS 14.4.1
Browser
Google Chrome 128.0.6613.113
Code of Conduct
The text was updated successfully, but these errors were encountered: