Pagefold

JS

Animate with JavaScript instead of CSS: GSAP, Motion, the Web Animations API or any library.

Import it from pagefold/js (about 1.2 KB minified and compressed, shared code included).

Each animation is an object:

{
  name: 'slide',           // optional: only runs when the visit asks for this name
  from: '/',               // optional: pattern or list of patterns, default any page
  to: '/blog/:slug',       // optional: same
  out: (done, data) => {}, // animate the old content out
  in: (done, data) => {},  // animate the new content in
}

You can pass the array directly: new PagefoldJs([ ... ]).

Read Animating with JavaScript for the contract, and the guides for GSAP, Motion and the Web Animations API.

Matching

  • :name matches one path segment, * or (.*) matches anything.
  • The query string is ignored and a trailing slash is optional. matchOptions changes that: { ignoreCase: true }, { strict: true } (the trailing slash has to match) and { end: false } (/blog also matches /blog/post).
  • Matching entries are checked in order. If the visit has an animation name, an entry with that name wins; otherwise the first entry without a name runs.
  • When nothing matches, the visit simply does not wait.

How it fits in

It replaces the default behavior of the animation:out:await and animation:in:await hooks. Handlers registered with .before or normally still run around it.

Which animation runs: examples

With these entries:

new PagefoldJs([
  { name: 'slide', out: slideOut, in: slideIn },
  { from: '/', to: '/blog/:slug', out: zoomOut, in: zoomIn },
  { out: fadeOut, in: fadeIn },
])
VisitRunsWhy
/ to /blog/hellozoomThe second entry matches both patterns and has no name
/about to /contactfadeNo pattern matches, so the first entry without a name runs
/about to /contact, link has data-pagefold-animation="slide"slideAn entry with the visit’s name wins, as long as its own patterns match
/ to /blog/hello, link has data-pagefold-animation="slide"slideThe name wins. The slide entry has no patterns, so it matches every visit

Put the most specific entries first and a plain fallback last. Without a fallback, pages that match nothing change instantly.

Common problems

  • The animation is skipped. No entry matched and there is no fallback, or the visit has animation.animate = false (for example a back-button visit). See Caching and history.
  • The page waits forever. An out or in that takes done never calls it, for example because of an exception before it. Pagefold has no timeout of its own here, so wrap risky code in try / finally.
  • Both CSS and JS animate. Set animationSelector: false so Pagefold does not also wait for CSS transitions.

Options

Option Type Default What it does
animations JsAnimation[] [] The animations. The first one whose from and to patterns match the visit runs.
matchOptions { ignoreCase?, strict?, end? } {} How path patterns are matched: ignoreCase (default false), strict (the trailing slash has to match, default false) and end (default true; false also matches the paths below).