How to correctly apply global scripts with Nextjs

I’m trying to apply a global fade-in animation to all components in my application. I’ve added the classname fadeIn to all the elements and set the opacity to 0 by default. I then use js to change that to 1 when the element comes into view.

Below is how I am applying this so far. It does work but there is a major issue and I’m sure it’s not the best method and firstly would love to know any better methods.

The major issue is that it only works on the first render. But if I navigate to another page and then come back, all elements are hidden with the opacity 0 and the script does not execute.

Appreciate any advice on how to either solve the current issue, or a better way to execute it.

_app.js

function MyApp({ Component, pageProps }) {

  return <Provider store={store}>
    <Layout>
      <PersistGate persistor={persistor}>
        <Component {...pageProps} />
      </PersistGate>
      <FadeIn />
    </Layout>
  </Provider>
}

export default MyApp

FadeIn component

import React, { useEffect, useState } from 'react'
import Script from 'next/script'
import ReactDOM from 'react-dom';

export default function FadeIn() {

  const myScript = (
    <Script src='/utils/scripts/appearOnScroll.js' strategy="afterInteractive" />
  )

  return ReactDOM.createPortal(myScript, document.getElementById('doc-root'));

}

appearOnScroll.js

(function () {
  const faders = document.querySelectorAll('.fade-in');
  const faderOptions = {
    threshold: 1
  };
  const appearOnScroll = new IntersectionObserver(function (
    entries,
    appearOnScroll
  ) {
    entries.forEach(entry => {
      if (!entry.isIntersecting) {
        return;
      } else {
        entry.target.classList.add('appear');
        appearOnScroll.unobserve(entry.target);
      }
    })
  }, faderOptions);

  faders.forEach(fader => {
    appearOnScroll.observer(fader);
  });
})();