I’m having trouble with
Lazy loading page sections using Velo code and the onViewportEnter event—the event isn’t firing for collapsed sections.
Working in
Wix Studio Editor, Dev Mode (Velo)
Site link
https://www.edhike.in/
What I’m trying to do
I want to implement lazy loading for multiple page sections. My goal is for sections (e.g., section1, section2, etc.) to reveal with a smooth animation only when a user scrolls them into view. I’m using Velo’s onViewportEnter for each section component to trigger the expand/show action.
What I’ve tried so far
Collapsing all sections (except the hero) on page load, then adding section.onViewportEnter(() => { section.expand() }) to each.
-
Using both
hide()andcollapse()—neither triggersonViewportEnteras expected. -
Checked Velo documentation and forum posts; most examples either use visible sections or a different triggering mechanism.
-
Tried scroll handlers and Intersection Observers, but they complicate the layout handling for true sections.
-
Added console logs to verify the callback, but it’s never reached for collapsed sections.
Extra context
It seems like sections that are collapsed, and therefore not rendered in the DOM/layout flow, cannot trigger the onViewportEnter event. Ideally, I’d like to keep sections out of the DOM for performance (using collapsed), but still reveal them on scroll with an animation and minimal initial page weight. Has anyone found a reliable pattern for this? Any official clarification on viewport events and collapsed sections would help. Example code and edge-case solutions appreciated!
Here is code I am using inside velo code editor for a particular page :
$w.onReady(function () {
const sections = $w(‘Section’);
if (sections.length === 0) return;
const [firstSection, …otherSections] = sections;
otherSections.forEach((section, index) => {
if (!section.hidden) section.hide(); // hide, not collapse
});
otherSections.forEach((section, idx) => {
section.onViewportEnter(() => {
setTimeout(() => {
section.show(‘fade’, { duration: 600 });
}, idx * 200);
});
});
});


