guide / scrollreveal in react3 steps

ScrollReveal, per component.

ScrollReveal is GPL-3.0, with a paid licence for commercial work, and has not shipped since 4.0.9. svg-scroll-draw/scrollreveal is an independent MIT implementation of the same API, and its React entry reveals each component as it mounts instead of once at start-up.

importscrollrevealsvg-scroll-draw/scrollreveal
version4.0.9 · 20222.23.3 · maintained
licenceGPL-3.0MIT
gzip5.6 KB4.7 KB
in ReactYour own effectuseScrollReveal
Fig. 1 — what changes, measured
01The problem

What goes wrong with the usual setup

  1. 1The usual setup is one ScrollReveal().reveal(".card") when the app starts. reveal() only finds the elements that exist at that moment, so components that mount later — a new route, a list that loads — are not revealed unless you call sync().
  2. 2Nothing cleans up when a component unmounts unless you call clean() yourself.
  3. 3ScrollReveal is licensed GPL-3.0 for open source and non-commercial use; commercial sites need a paid licence.
023 steps

The switch, step by step

  1. Step 01 · terminal

    Switch the package — one command

    Points every scrollreveal import at the drop-in and swaps the dependency. Your ScrollReveal() calls do not change.

    terminal3 lines
    npx svg-scroll-draw migrate --dry-run
    npx svg-scroll-draw migrate
    npm install
  2. Step 02 · Features.jsx

    Reveal from the component that renders the content

    useScrollReveal returns a ref. Put it on the element to reveal — or on a container and pass selector to reveal its children, which is how an interval sequence is written. In Next.js, use it in a client component.

    Features.jsx13 lines
    'use client';
    import { useScrollReveal } from 'svg-scroll-draw/scrollreveal/react';
    
    export function Features({ items }) {
      const ref = useScrollReveal({ selector: '.card', interval: 80, distance: '40px' });
      return (
        <section ref={ref}>
          {items.map((item) => (
            <div className="card" key={item.id}>{item.title}</div>
          ))}
        </section>
      );
    }
  3. Step 03 · main.jsx

    Keep shared defaults where they were

    ScrollReveal({ ... }) still sets defaults for every later reveal, exactly as before.

    main.jsx3 lines
    import ScrollReveal from 'svg-scroll-draw/scrollreveal';
    
    ScrollReveal({ duration: 800, easing: 'cubic-bezier(0.5, 0, 0, 1)' });
03unchanged

What stays exactly the same

  • Every option: distance, origin, opacity, scale, rotate, delay, duration, easing, interval, reset, useDelay, viewFactor, viewOffset, container, mobile, desktop, cleanup and the four callbacks.
  • The inline styles written — the browser test suite runs ScrollReveal 4.0.9 beside the drop-in and requires them to match byte for byte.
  • The sr class on <html> that anti-flash CSS keys off.
04questions

Questions

Q1

Is this really MIT?

Yes. It is an independent implementation written from ScrollReveal’s behaviour, with no ScrollReveal code in it, and the whole package is MIT.

Q2

Do I have to use the hook?

No. import ScrollReveal from 'svg-scroll-draw/scrollreveal' works exactly like ScrollReveal; the hook adds the mount and unmount handling.

Q3

Does it work in the Next.js App Router?

Yes, in client components. The entry is marked "use client".

05More guides

More migration guides