Astro GSAP ScrollTrigger
Purpose
Use GSAP in Astro without breaking static rendering, route transitions, accessibility, or mobile performance.
Required Pattern
- Keep all
window,document,matchMedia,gsap, andScrollTriggerinitialization inside client-side<script>blocks or imported browser scripts. - Never access browser APIs in Astro frontmatter; frontmatter runs on the server/build side.
- Register
ScrollTriggeronce in the browser script. - Initialize on
astro:page-load. - Cleanup on
astro:before-swap. - Respect
prefers-reduced-motion: reduce. - Animate only
transformandopacityunless there is a measured reason. - Call
ScrollTrigger.refresh()after layout-affecting images/content are ready.
Minimal Lifecycle Shape
<script>
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
let ctx;
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
function cleanup() {
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
ctx?.revert?.();
ctx = undefined;
}
function init() {
cleanup();
if (reduceMotion.matches) return;
ctx = gsap.context(() => {
gsap.to('[data-narrative]', {
opacity: 1,
y: 0,
duration: 0.7,
ease: 'power3.out',
scrollTrigger: {
trigger: '[data-narrative]',
start: 'top 85%',
},
});
});
requestAnimationFrame(() => ScrollTrigger.refresh());
}
document.addEventListener('astro:page-load', init);
document.addEventListener('astro:before-swap', cleanup);
if (document.readyState !== 'loading') init();
</script>
Review Checklist
- Does the page still render meaningful content without JavaScript?
- Does reduced motion show content immediately?
- Does route navigation avoid duplicate triggers?
- Are pinned sections bounded and mobile-safe?
- Are images/layout changes followed by a refresh?
- Are there no global scroll listeners doing animation work manually?
Tool Routing
- Use
astro-frameworkfor Astro lifecycle and routing. - Use
webapp-testingorbrowserto verify console errors and layout behavior. - Use
web-motion-libraryonly for generic animation inspiration. - Use
animejsonly inside HyperFrames compositions; do not substitute it for live Astro ScrollTrigger work unless explicitly requested.