Reinitialize ix3 animation engine with SWUP or BARBA.js — Webflow interactions with GSAP

Hey guys, I’m facing an interesting challenge.

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?

Thanks in advance!

2 Likes

I have the same issue at the moment. I cant reinit the new GSAP animations after smooth page transitions. Anyone knows how to reinit?

3 Likes

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 ;-)
2 Likes

I’ll definitely take a look at the css transitions. I didn’t know they were so widely available.

Regarding the snippet Webflow gives: that is what I’m having trouble with, that line of code seems to not reinit the engine.

That’s my current challenge.

Thanks for you help.

1 Like

I think I found the solution.

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.

—L

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

  1. Updating data-wf-page on tag before reinitializing Webflow

  2. Calling Webflow.destroy() and Webflow.ready()

  3. Reinitializing IX2: Webflow.require(‘ix2’).destroy() and .init()

  4. Dispatching internal stop action: ix2.store.dispatch(ix2.actions.stop())

  5. Firing browser events: readystatechange, load, resize

  6. Re-executing the Webflow bundle script

  7. Calling ScrollTrigger.refresh()

Result: IX2 (legacy interactions) reinitialize correctly. IX3 does not because the module itself is never loaded into memory.

What’s Needed

For IX3 to work with SPA navigation (Barba.js, Swup, etc.), we need one of the following:

  1. A method to dynamically load the IX3 module after initial page load

  2. A public API to initialize IX3 animations on demand (similar to ix2.init())

  3. An option to force IX3 to always load regardless of which page is loaded first

  4. Documentation on the recommended approach for using IX3 with SPA frameworks

Current Workaround Options

  • Recreate IX3 animations manually with custom GSAP code (duplicates work done in Webflow)

  • Add a hidden IX3 animation to every page so IX3 always loads (hacky)

    Anyone knows if there a supported way to force-load or reinitialize the IX3 module after a Barba.js/Swup page transition?

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.