Handling page transitions in Plasmic (Codegen) and some other issues.

I’ve set up global page transitions using Framer Motion’s AnimatePresence.

Here is a semi-working demo:

Here is my code:

"use client";
import { motion, AnimatePresence } from "framer-motion";
import '@/styles/globals.css';
import { PlasmicRootProvider } from "@plasmicapp/react-web";
import type { AppProps } from "next/app";
import Head from "next/head";
import { NextUIProvider } from "@nextui-org/react";
import { useRouter } from "next/router";
import Navbar from "../components/Navbar";
import { useLayoutEffect, useEffect, useState } from "react";

export default function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter();
  const [scrollPosition, setScrollPosition] = useState(0);

  useLayoutEffect(() => {
    document.body.style.height = "100%";
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.height = "";
      document.body.style.overflow = "";
    };
  }, []);

  useEffect(() => {
    const handleRouteChangeStart = () => {
      setScrollPosition(window.scrollY);
    };

    const handleRouteChangeComplete = () => {
      window.scrollTo(0, scrollPosition);
    };

    router.events.on("routeChangeStart", handleRouteChangeStart);
    router.events.on("routeChangeComplete", handleRouteChangeComplete);

    return () => {
      router.events.off("routeChangeStart", handleRouteChangeStart);
      router.events.off("routeChangeComplete", handleRouteChangeComplete);
    };
  }, [router.events, scrollPosition]);

  return (
    <>
      <Head>
        <link rel="stylesheet" href="/output.css" />
      </Head>
      <PlasmicRootProvider Head={Head}>
        <NextUIProvider>
          <>
            <Navbar />
            <AnimatePresence mode="wait" initial={false}>
              <motion.div
                key={router.route}
                initial={{ y: 50, opacity: 0 }}
                animate={{ y: 0, opacity: 1 }}
                exit={{ y: -50, opacity: 0 }}
                transition={{ ease: "easeInOut", duration: 0.75 }}
              >
                <Component {...pageProps} />
              </motion.div>
            </AnimatePresence>
          </>
        </NextUIProvider>
      </PlasmicRootProvider>
    </>
  );
}

Now, I’ve tried everything to achieve my desired behaviour but unfortunately I can’t get there. Ideally, of course, I want Page A to keep its position as it transitions to page B (I’ve achieved this) but the side effect of having achieved that is it now assumes the same position on page B.

I want page A to maintain its position while either transitioning to the top or the relevant anchor of page B.

Bonus Question:

You’ll see I used my plasmic navbar component inside , so as to exclude it from page animations. This presents two issues. 1) I now have a navbar in studio. 2) I’m unsure how to expose the current page URL to the navbar component to achieve the “current page” effect you can see with the blue line in the video.

Am I doing all of the above at the wrong place in my heirarchy?

I have a few questions unanswered on the forum but this one is fairly pressing so I’ll nudge it for urgency :smiley: in the meantime, feel free to let me know if my approach is just totally wrong and if I need to look elsewhere with regards to page transitions

I think the state is maintained at the right level such that it can be persisted across pages. Have you tried changing the single scroll position state to a mapping from page URL to scroll position instead?

No luck. Though, unsure I’m doing it right. Are you able to assist?

Can you post the updated code?