I honestly love this forum, you guys offer some of the best support I've come across. 😅
You are of course correct, my particular setup is a Next.js app, so either SSR pages or Static pages that are pre-rendered on the server. (Don't know why I didn't mention that earlier 🤦♂️)
I've gotten it to work using Blake's useEffect suggestion, though I needed to check for window even inside the useEffect, makes sense to me.
For anyone else's benefit, here's the final working code:
useEffect(() => {
// make sure we're in browser land for gsap plugin registration
if (typeof window !== "undefined") {
// register gsap ScrollTrigger plugin
gsap.registerPlugin(ScrollTrigger);
// Set up timeline
const tl = gsap.timeline({
scrollTrigger: {
trigger: triggerPointRef.current,
scrub: true,
start: "top",
},
});
// Configure the timeline animation
tl.from(letterRefs.current, {
duration: 1,
y: 200,
opacity: 0,
stagger: 0.02,
});
}
}, [letterRefs]);
And for all the people finding this via google, here's a bunch of words...
React / Next.js gsap ScrollTrigger, Please gsap.registerPlugin(ScrollTrigger) TypeError: _toArray is not a function.
There is probably a more elegant solution than this, because thinking about it, this useEffect lives inside this particular component, there could be multiple of these on the page together, so it seems to me like registering multiple instances of ScrollTrigger is probably going to cause issues / not be best practice.
Am I right in my thinking guys? Perhaps a useEffect in the top level app component to register the plugin once so it's available to use in child components that call it? Any suggestions welcome 😄
Thank you Zach, Jack & Blake!