Next.js Discord

Discord Forum

Modal with parallel routing scrolls the background contents on OPEN

Unanswered
Northern Mockingbird posted this in #help-forum
Open in Discord
Northern MockingbirdOP
This works almost perfectly except for that one problem. Clicking on the image (in commissions/page.js as you'll see below) opens the modal, I can scroll in the background (which I like), and close the modal.

1) When I open the modal, it scrolls to the bottom of the page in the background (behind the modal overlay)

2) When I close the modal, the screen returns to the same scroll position the page was on when I opened the modal. Makes scrolling pointless.

These 2 behaviors make the background contents look too sporadic.

Here is my route directory:
/root/app
  /commissions
    page.js
    /[slug]
      page.js
  @modal
    (.)commissions/[slug]
      page.js


The image grid is in /app/commissions/page.js:
commissions.map((commission) => (
  <Link
    key={commission.id}
    href={`/commissions/${commission.slug.current}`}
    className="commission-link"
  >
    <Image
      alt={commission.title}
      src={urlForImage(commission.image).url()}
      width={400}
      height={600}
    />
  </Link>
))


The modal page.js:
return (
  <Modal>
    <Image
      alt={commission.title}
      src={urlForImage(commission.image).url()}
      width={550}
      height={700}
      className="commission-modal"
    />
  </Modal>
);

3 Replies

Northern MockingbirdOP
Since my post was too long, I'll post my Modal component code in this message.

<Modal> component:
'use client';
import { useCallback, useRef, useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function Modal({ children }) {
  const overlay = useRef(null);
  const wrapper = useRef(null);
  const router = useRouter();

  const onDismiss = useCallback(() => {
    router.back();
  }, [router]);

  const onClick = useCallback(
    (e) => {
      if (e.target === overlay.current || e.target === wrapper.current) {
        if (onDismiss) onDismiss();
      }
    },
    [onDismiss, overlay, wrapper]
  );

  const onKeyDown = useCallback(
    (e) => {
      if (e.key === 'Escape') onDismiss();
    },
    [onDismiss]
  );

  useEffect(() => {
    document.addEventListener('keydown', onKeyDown);
    return () => document.removeEventListener('keydown', onKeyDown);
  }, [onKeyDown]);

  return (
    <div ref={overlay} className="modal-overlay" onClick={onClick}>
      <div ref={wrapper} className="modal-wrapper">
        {children}
      </div>
    </div>
  );
}
Northern MockingbirdOP
I didn't know about that scroll property. Thanks. That solved the issue of the page scrolling down on modal open.
My background scrolling isn't persisting though, so I decided I'll just prevent background scrolling