On the PLP, clicking a product redirects to the PDP, but when hitting the browser’s back button, the scroll position on the collection page is lost and it goes back to the top. I created a component that saves the scroll position, but I noticed that products are loaded as you scroll down the page, which causes discrepancies in the position. Another issue is that when using pagination while loading on the PLP, products load continuously and all of them are displayed — but if you go to the PDP and come back, only the maximum number of products for that page is returned.
Example: the product limit is 20, and with pagination you’d see 60 products on one page, but after going to the PDP and coming back, only the 20 products for that specific page are shown. Has anyone run into this?
@fabiano.dev How’s it going?
This issue is quite common on product listing pages (PLPs) with infinite dynamic loading and pagination. The behavior of losing the scroll position and the correct number of products when navigating back from the PDP can be caused by a few factors, such as the browser’s default behavior and page state management.
Possible solutions to handle the problem:
- Storing the Scroll Position:
-
The component you created to store the scroll position is an important step, but make sure you’re saving it somewhere that won’t be lost when navigating to the PDP and back, such as
localStorageorsessionStorage. -
When returning to the PLP, you can manually restore the scroll position after the products have fully loaded.
Possible example:
window.addEventListener('beforeunload', () => { localStorage.setItem('scrollPosition', window.scrollY); }); window.addEventListener('load', () => { const scrollPosition = localStorage.getItem('scrollPosition'); if (scrollPosition) { window.scrollTo(0, parseInt(scrollPosition, 10)); } });
- Managing Pagination Correctly:
- The behavior you described — where the page loads a larger number of products as you scroll (e.g. 60), but when you return from the PDP it only shows the default 20 products — happens because the PLP is being re-rendered based on default data rather than the previous navigation state. To fix this, you can store the page state (including the number of loaded products and the current page) before navigating to the PDP. This can be done using localStorage or sessionStorage.
Possible example:
// Store the page state before going to the PDP
const state = {
productsLoaded: [...document.querySelectorAll('.product-item')].length,
currentPage: currentPaginationPage
};
localStorage.setItem('plpState', JSON.stringify(state));
// Restore the state when coming back
const savedState = JSON.parse(localStorage.getItem('plpState'));
if (savedState) {
loadProducts(savedState.productsLoaded);
setCurrentPage(savedState.currentPage);
}
- Avoiding a Full Page Reload:
- When the user returns to the PLP, the page is reloading and re-fetching the products. Ideally, you’d want to avoid a full page reload when navigating between the PDP and PLP, using something like React Router or AJAX to load PDPs dynamically while keeping the PLP state intact.
- Infinite Scroll with Continuous Pagination:
- To fix the behavior where the products loaded on the PLP are reset when returning from the PDP, you can ensure that the infinite scroll component continues loading products from the page where the user left off, rather than starting over from scratch.
- One approach would be to use an observer or trigger to detect when products need to be loaded, making sure the pagination state is preserved and restored correctly.
- Persisting State on the Server:
- Another more robust approach would be to persist the navigation and pagination state on the server or application backend, so that even if the user leaves the PLP, the loaded products, current page, and scroll position remain in sync between client and server.
Notes:
These solutions vary in complexity depending on how your PLP is built and structured. Storing the scroll position and pagination state in localStorage or sessionStorage is the simplest and most effective approach for most cases. Using React or AJAX may be necessary for smoother navigation between pages.
Another important thing to keep in mind is the use of customizations. VTEX clearly does not support custom components. So you need to make sure you’re following industry best practices to avoid headaches down the road if the code ever needs to be maintained or adapted.
I hope this information helps you find a path to a solution. If it does, please mark it as the solution to help others in the community.
Cheers,
Estevão.
@estevao_santos, thank you once again for the contribution!
This situation is something that other devs have raised with VTEX as shown in this issue. I’m using VTEX’s native category and collection pages — the scroll position saving works fine without pagination, but as I paginate through and click on a product to go to the PDP and then hit back, in some cases the page loads showing products only from the last pagination I accessed. Attached is a video simulating this on VTEX’s store theme. I’ll keep trying on my end, as the client is insisting on this
.
@fabiano.dev No problem!
I see. It might be something that genuinely doesn’t have a viable solution. In that case, I’d let the client know it’s a limitation and there’s not much we can do about it. On top of that, if something is implemented, it might not be 100% perfect and could end up causing more problems than just leaving it as is.
Have you tried combining 2 ideas: storing the page state + scrolling to the selected product when returning.
All of this using localStorage.
See if this works:
Capturing the page state and scrolling back on return from the PDP:
// Store the scroll position and page state before going to the PDP
window.addEventListener('beforeunload', () => {
const state = {
scrollPosition: window.scrollY,
currentPage: currentPaginationPage, // Save the current pagination page
productsLoaded: [...document.querySelectorAll('.product-item')].length
};
localStorage.setItem('plpState', JSON.stringify(state));
});
// Restore the scroll position and state when returning to the PLP
window.addEventListener('load', () => {
const savedState = JSON.parse(localStorage.getItem('plpState'));
if (savedState) {
// Restore the pagination page number and loaded products
setCurrentPage(savedState.currentPage);
loadProducts(savedState.productsLoaded);
// After loading the products, restore the scroll position
window.scrollTo(0, parseInt(savedState.scrollPosition, 10));
// Clear the saved state after restoring
localStorage.removeItem('plpState');
}
});
How would it work?
- Saves the current page: In addition to saving the scroll position, we’re also saving the current pagination page (
currentPaginationPage). When the user returns from the PDP, the system reloads that specific PLP page. - Restores the scroll position: As soon as the correct page is reloaded, the scroll position is restored.
- State cleanup: After restoring the page state and scroll, localStorage is cleared to avoid accumulating unnecessary data.
See if this makes any difference in your case.
Honestly, beyond that, I don’t see another positive scenario at the moment.
Cheers,
Estevão.