Mastering Wix Studio: Seamless Back Navigation for CMS Repeaters with Velo
As a Wix migration expert and community analyst, I frequently observe common challenges users face when building sophisticated, data-driven websites. One such challenge, highlighted in a recent Wix Studio community forum topic, revolves around maintaining a seamless user experience when navigating between CMS-connected repeater pages and their associated dynamic item pages. This issue, specifically the inability of a 'back' button to return to the exact scroll position on a repeater page, is critical for sites utilizing 'Load More' functionality, such as an artist's portfolio.
Unlocking Seamless User Experience: Restoring Scroll Position on Wix Studio CMS Repeaters
The core of the problem, as described by the user building an artist's site, is that clicking a 'back' button from a dynamic artwork details page always returns the visitor to the very top of the 'All Artworks' page. This is incredibly disruptive, especially when the repeater has loaded many items via a 'Load More' button, forcing the user to re-scroll and potentially re-load content to find their previous spot. This article will provide a clear, Velo-based solution to address this specific pain point, ensuring visitors return to their precise scroll position and the correct number of loaded repeater items.
The Challenge: A Common User Experience Frustration
The original forum post succinctly captures the issue: "Need back button to jump back to scroll position not top of page on dynamic page connected to CMS... The issue I have is that when you click the 'back button' on the dynamic page it navigates you back to the top of the All Artworks page. I need it to navigate you back to exactly where you were in the scroll navigation. An important note: the repeater only displays 6 artworks at a time (with a Load More button to display more) and so I need to code to take that into consideration and correctly navigate you back to where you were in the repeater's load."
This scenario is common for e-commerce sites, portfolios, blogs, and directories built with Wix Studio and its powerful CMS. Without a solution, users experience frustration, which can lead to higher bounce rates and a less professional site perception. The key is to capture the state of the repeater page (scroll position and number of loaded items) before navigation and then restore it upon return.
The Velo Solution: Leveraging sessionStorage for Seamless Navigation
The solution involves using wix-storage.session to temporarily store the necessary page state. sessionStorage is ideal for this as it persists data across page reloads within the same browser tab, but clears once the tab is closed, making it perfect for temporary navigation state management.
1. Capturing State Before Navigation (Your Repeater Page)
Before a user navigates from the repeater page to a dynamic item page, we need to record two crucial pieces of information:
- The current vertical scroll position of the window (
wix-window.scrollY). - The total number of items currently displayed in the repeater. This is especially important for 'Load More' scenarios.
This data will be saved into sessionStorage within the repeater item's onClick event handler.
2. Restoring State Upon Return (Your Repeater Page)
When the repeater page loads (or reloads, as in the case of navigating 'back'), its $w.onReady function will check if there's any stored scroll position or loaded item count in sessionStorage. If found, the page will:
- Re-fetch and display the correct number of items in the repeater to match the previously loaded state.
- Use
wix-window.scrollTo()to return the user to their exact previous scroll position. - Clear the
sessionStorageitems to ensure this restoration only happens once per navigation cycle.
3. The Dynamic Page's "Back" Button
On the dynamic page, the 'back' button simply needs to navigate back to the previous page in the browser's history, which will trigger the repeater page's $w.onReady function to restore the state.
Step-by-Step Implementation Guide
Here's how to implement this solution using Velo. For this example, we'll assume your CMS collection is named "Artworks", your repeater is #artworkRepeater, the clickable element within each repeater item is #artworkImage, and your dynamic page URL structure is /artworks/{slug}.
-
Prepare Your Repeater Page Code (e.g.,
artworks-page.js)This code block will manage fetching and displaying your artworks, handling the 'Load More' button, and crucially, saving the scroll state when an artwork is clicked.
import wixLocation from 'wix-location'; import { session } from 'wix-storage'; import wixWindow from 'wix-window'; import wixData from 'wix-data'; let allArtworks = []; // To store all fetched artworks (or a large chunk) const itemsPerPage = 6; let currentDisplayedItems = 0; $w.onReady(function () { // Check if returning from a dynamic page with stored state if (session.getItem("scrollPosition") && session.getItem("loadedItemsCount")) { const storedScrollPosition = parseInt(session.getItem("scrollPosition"), 10); const storedLoadedItemsCount = parseInt(session.getItem("loadedItemsCount"), 10); fetchAndDisplayArtworks(storedLoadedItemsCount) .then(() => { wixWindow.scrollTo(0, storedScrollPosition); // Clear session storage after use session.removeItem("scrollPosition"); session.removeItem("loadedItemsCount"); }); } else { // Initial page load or normal navigation fetchAndDisplayArtworks(itemsPerPage); } // "Load More" button handler $w("#loadMoreButton").onClick(() => { fetchAndDisplayArtworks(currentDisplayedItems + itemsPerPage); }); }); async function fetchAndDisplayArtworks(numItemsToDisplay) { if (allArtworks.length === 0) { // Fetch all artworks once if not already fetched. // Adjust limit based on your expected total items to avoid excessive queries. const results = await wixData.query("Artworks") // Replace "Artworks" with your collection ID .limit(1000) .find(); allArtworks = results.items; } // Display the required number of items $w("#artworkRepeater").data = allArtworks.slice(0, numItemsToDisplay); currentDisplayedItems = numItemsToDisplay; // Manage Load More button visibility if (currentDisplayedItems < allArtworks.length) { $w("#loadMoreButton").show(); } else { $w("#loadMoreButton").hide(); } } // Repeater item click handler to save state export function artworkRepeater_itemReady($item, itemData, index) { $item("#artworkImage").onClick(() => { // Assuming #artworkImage is the clickable element session.setItem("scrollPosition", wixWindow.scrollY.toString()); session.setItem("loadedItemsCount", currentDisplayedItems.toString()); wixLocation.to(`/artworks/${itemData.slug}`); // Navigate to dynamic page }); } -
Configure Your Dynamic Page's "Back" Button (e.g.,
artwork-details-page.js)On your dynamic page, implement a simple
onClickhandler for your "back" button. Ensure you have a button element (e.g.,#backButton) on your dynamic page.import wixLocation from 'wix-location'; $w.onReady(function () { // Assuming you have a back button with ID "backButton" $w("#backButton").onClick(() => { wixLocation.back(); // Navigates to the previous page in history }); });
Key Considerations for Robust Implementation
- Error Handling: Always consider adding
try-catchblocks around data fetching operations to gracefully handle potential errors, especially withwixDataqueries. - Performance: For very large datasets (thousands of items), fetching 'allArtworks' at once might impact initial load time. Consider implementing a more advanced pagination strategy directly within
fetchAndDisplayArtworksif this becomes an issue, fetching only the necessary chunks. For most artist portfolios, the current approach is efficient. - User Experience: While the scroll position is restored, consider adding a subtle visual cue (e.g., a brief fade-in animation) to the repeater when items are reloaded to make the transition even smoother.
- Testing: Thoroughly test this functionality across different browsers, devices, and network conditions to ensure consistent behavior. Pay close attention to how the 'Load More' button behaves after returning.
Conclusion
By implementing these Velo code snippets, Wix Studio store owners and developers can significantly enhance the user experience on their CMS-driven sites. The ability to seamlessly return to the exact scroll position on a repeater page, even with dynamic content loading, transforms a potentially frustrating interaction into an intuitive and professional navigation flow. This solution demonstrates the power of Velo to customize Wix Studio beyond its out-of-the-box capabilities, creating truly polished and user-friendly web experiences.