jsonkao / react-scrollama

Simple scrollytelling with the IntersectionObserver in React.
https://jsonkao.github.io/react-scrollama
MIT License
388 stars 30 forks source link

2.0.3-beta breaks next.js (throws error under ssr, no workaround) #66

Closed gjhltn closed 2 years ago

gjhltn commented 3 years ago

Version 2.3.0-beta.0 introduces an incompatibility with next.js SSR. As v2.3.0-beta.0 fixes other dealbreaker issues (https://github.com/jsonkao/react-scrollama/issues/19#issuecomment-844374760) this is a blocker problem for me.

Overview

1) Under next.js, after upgrading to 2.3.0-beta.0, previously working code now throws the error

Server Error 
ReferenceError: window is not defined

2) There's a standard workaround for this sort of problem - using dynamic imports. However if you attempt this (which btw also works as expected under 2.2.16 even though there's no need for it) with 2.3.0-beta.0 you get a Scrollama error

Unhandled Runtime Error 
SyntaxError: Failed to construct 'IntersectionObserver': rootMargin must be specified in pixels or percent

3) Similar next.js workarounds (eg using process.browser) also generate the same error.

So at present it looks like using the library with next.js is not possible at all.

Steps to reproduce 1 (window error)

(the no-frills example from the Readme, unmodified):

pages/index.js

import React, { useState } from 'react';
import { Scrollama, Step } from 'react-scrollama';

const ScrollamaDemo = () => {
  const [currentStepIndex, setCurrentStepIndex] = useState(null);

  // This callback fires when a Step hits the offset threshold. It receives the
  // data prop of the step, which in this demo stores the index of the step.
  const onStepEnter = ({ data }) => {
    setCurrentStepIndex(data);
  };

  return (
    <div style={{ margin: '50vh 0', border: '2px dashed skyblue' }}>
      <div style={{ position: 'sticky', top: 0, border: '1px solid orchid' }}>
        I'm sticky. The current triggered step index is: {currentStepIndex}
      </div>
      <Scrollama onStepEnter={onStepEnter} debug>
        {[1, 2, 3, 4].map((_, stepIndex) => (
          <Step data={stepIndex} key={stepIndex}>
            <div
              style={{
                margin: '50vh 0',
                border: '1px solid gray',
                opacity: currentStepIndex === stepIndex ? 1 : 0.2,
              }}
            >
              I'm a Scrollama Step of index {stepIndex}
            </div>
          </Step>
        ))}
      </Scrollama>
    </div>
  );
};

export default ScrollamaDemo;

Steps to reproduce 2 (IntersectionObserver error)

pages/index.js

import React, {useState} from "react"
import dynamic from 'next/dynamic'

const ScrollamaDemo = dynamic(
    () => import('../components/ScrollamaDemo'),
    { ssr: false }
)

const Page = () => 
    <div><ScrollamaDemo/></div>

export default Page

components/ScrollamaDemo.js

import React, {useState} from "react"
import { Scrollama, Step } from 'react-scrollama'

const ScrollamaDemo = () => {
  const [currentStepIndex, setCurrentStepIndex] = useState(null);
  const onStepEnter = ({ data }) => {
    setCurrentStepIndex(data);
  };

  return (
    <div style={{ margin: '50vh 0', border: '2px dashed skyblue' }}>
      <div style={{ position: 'sticky', top: 0, border: '1px solid orchid' }}>
        I'm sticky. The current triggered step index is: {currentStepIndex}
      </div>
      <Scrollama onStepEnter={onStepEnter} debug>
        {[1, 2, 3, 4].map((_, stepIndex) => (
          <Step data={stepIndex} key={stepIndex}>
            <div
              style={{
                margin: '50vh 0',
                border: '1px solid gray',
                opacity: currentStepIndex === stepIndex ? 1 : 0.2,
              }}
            >
              I'm a Scrollama Step of index {stepIndex}
            </div>
          </Step>
        ))}
      </Scrollama>
    </div>
  )
}

export default ScrollamaDemo
robhawkes commented 2 years ago

The second issue is similar to one I hit and can be resolved using this approach: https://github.com/jsonkao/react-scrollama/issues/74#issuecomment-1074097206