barba-spa-transitions
Barba.js SPA Transitions
When to use this
- Adding SPA-style page transitions to a traditional multi-page site (WordPress, static HTML, server-rendered).
- Using GSAP + ScrollTrigger and needing to reinitialize animations after each page swap.
- Building a portfolio or editorial site with distinct transition styles per page type (home-to-project vs project-to-project).
- Wanting prefetch and caching without a full SPA framework.
- Do NOT use this for React/Next.js apps; use
page-transition-choreographywith Framer Motion or View Transitions API instead.
Mental model
Barba intercepts link clicks, fetches the target page via XHR, and swaps the content inside a wrapper element. It does not use the History API's pushState for rendering; it handles that internally. Your job is to define transitions that run during the lifecycle.
The lifecycle is: click -> before-leave -> leave (async) -> after-leave -> before-enter -> enter (async) -> after-enter. The leave and enter hooks are where your GSAP/CSS animations go. They receive a done callback (or you return a Promise) to signal completion. Barba waits for leave to finish before swapping the DOM and starting enter.
Barba operates on containers and wrappers. The wrapper ([data-barba="wrapper"]) persists across navigations. The container ([data-barba="container"]) is the element that gets replaced. Everything outside the wrapper is untouched (nav, footer if you want them persistent).
Namespaces let you create page-type-specific transitions. Each container has a data-barba-namespace (e.g., "home", "project", "about"). Transitions can target specific from/to namespace pairs, so home -> project can use a different animation than project -> project.
The biggest pitfall is script reinitialization. After Barba swaps the container, any JS that ran on DOMContentLoaded for the old page is dead. ScrollTrigger instances, event listeners, IntersectionObservers, and third-party widgets all need to be torn down and rebuilt. This is where 90% of Barba bugs come from.