I’m working on a site with animations crafted with the new interactions by gsap native in Webflow.
In addition, I’m using swup for smooth page transitions (swup is a lightweight barba js alternative).
When a page transition occurs, the gsap animations tied to scroll position and page load no longer work, no longer get triggered.
I found that for the old ix2 engine, there was a snippet that would reinitialize the engine, but after spending a few hours on it, it doesn’t seem to work for the new engine—seems like Webflow does not give that control to users.
Can someone advise how I can reinitialize the ix3 engine after a page swup?
I don’t have a direct fix, but here are two things you could try:
When you create a custom trigger with GSAP it gives you a code you can copy that triggers the animation. And inside this code there is a part that I think initializes IX3: const wfIx = Webflow.require(“ix3”)
In my last project I started using view-transitions with pure CSS (its a new set of CSS rules for page-transitions). Most browsers support it since 2025 (only Firefox doesn’t support it yet). The good thing regarding browser compatibility is that if a browser doesnt support CSS view-transitions it just falls back to normal page transition (with no animation).
I also used swup.js a few years ago and CSS view-transitions seem like a nice alternative and you can do a lot of cool stuff with it. I also combined it with GSAP animations and had no problems.
– Just as an alternative, if you’re not too deep into swup.js yet ;-)
I asked ChatGPT and Grok’s latest models, and they were not able to come up with the solution, thankfully the new Gemini 3 from google was able to find the issue.
Here’s what it gave me.
<script>
/**
* Webflow IX2/IX3 “Hard Reset” for Swup/Barba
* * overcoming the “stuck animations” issue in Webflow’s new GSAP engine.
* * THE SECRET SAUCE:
* 1. It updates the global `data-wf-page` ID (critical for mapping interactions).
* 2. It destroys the old instance to clear memory/listeners.
* 3. It manually fires ‘readystatechange’ which the new engine listens for.
*/
// 1. Define the Reset Function
function forceWebflowRestart() {
console.log('Force-restarting Webflow IX engine...');
// A. Clean up the old instance
// This removes event listeners and clears the legacy state
if (window.Webflow) {
window.Webflow.destroy();
window.Webflow.ready();
}
// B. The “Nuclear” Option for IX2/IX3
// We access the internal interaction module directly
if (window.Webflow && window.Webflow.require(‘ix2’)) {
const ix2 = window.Webflow.require(‘ix2’);
// If the store exists, we can try to dispatch a stop action
// (This part is often hidden, but .destroy() usually handles it.
// We re-init specifically to force a DOM re-scan).
if (ix2.store && ix2.actions) {
// Optional: Dispatch internal stop if needed, but init() is usually sufficient
// if the Page ID is correct.
ix2.store.dispatch(ix2.actions.stop());
}
// Initialize the engine. This parses the DOM for interaction triggers.
ix2.init();
}
// C. The “Kickstarter”
// The new GSAP engine often waits for the document to be “ready”
// to calculate bounding boxes. We fake this event.
document.dispatchEvent(new Event('readystatechange'));
// Optional: Trigger a resize to force ScrollTrigger to recalculate start/end points
window.dispatchEvent(new Event('resize'));
}
// 2. Initialize Swup (if you haven’t already)
const swup = new Swup({
// Your Swup options here
containers: \['#main-content'\] // standard webflow setup
});
// 3. Hook into the Lifecycle
swup.hooks.on(‘content:replace’, () => {
// CRITICAL STEP: Update the Page ID
// Webflow interactions are scoped to the specific Page ID found on the tag.
// Swup swaps the body, but NOT the html tag attributes by default.
// We must find the new Page ID in the incoming HTML and swap it manually.
// Note: Swup’s cache might store the parsed document.
// We need to grab the data-wf-page from the new page content.
// This approach assumes the new page content has been swapped into the DOM.
// However, since isn’t swapped, we look at the response or specific logic.
// A robust way if you have the new HTML string or document:
// (This is a simplified approach assuming you can get the ID from the new container
// or if you pass it via a script tag inside the container)
// ALTERNATIVE: Most Webflow+Swup setups put the Page ID on a hidden div inside the content
// to make it easy to grab.
// Example:
const newPageIdElement = document.querySelector(‘#page-id-transfer’);
if (newPageIdElement) {
const newPageId = newPageIdElement.getAttribute(‘data-page-id’);
const htmlTag = document.documentElement;
if (newPageId && htmlTag.getAttribute(‘data-wf-page’) !== newPageId) {
console.log(\`Swapping Page ID from ${htmlTag.getAttribute('data-wf-page')} to ${newPageId}\`);
htmlTag.setAttribute('data-wf-page', newPageId);
}
}
// 4. Execute the restart
forceWebflowRestart();
});
// Helper: Ensure this runs on the very first load too
document.addEventListener(‘DOMContentLoaded’, () => {
// Standard Webflow load usually handles this, but good to be safe
// window.Webflow.require(‘ix2’).init();
});
</script>
Essentially, the main issue in my way, was the html tag and page id were not changing, although the body was. This script forces that change to take place on each page swap.
This solution is for SWUP, but the same should apply for Barba.js and the like.
It worked like a charm for me.
Please let me know if this worked for you, I’d love to hear if you have any questions.
Good to know I am not the only one with this issue. Unfortunately the solution above didn’t solve it fully for me.
Webflow’s new GSAP-powered interactions (IX3) only work on initial page load. After navigating between pages using Barba.js, IX3 animations stop working.
Key Finding: The IX3 module is only loaded by Webflow’s webpack bundler if the initial page has IX3 animations. If a user lands on a page without IX3 animations first, then navigates to a page that has them, Webflow.require(‘ix3’) returns undefined because the module was never registered.
What I Tried
Updating data-wf-page on tag before reinitializing Webflow
Calling Webflow.destroy() and Webflow.ready()
Reinitializing IX2: Webflow.require(‘ix2’).destroy() and .init()
I found a solution. After I did what @levik mentioned. You also need to “Run on All pages“ in the setting of the IX3 animation. After that the IX3 loads on all pages.