How to Integrate Page Routing and Transitions in Next.js latest using layout.tsx and _app.tsx

165 Views Asked by At

I'm having trouble figuring out how to set up page routing with the new layout.tsx feature in Next.js. I have an _app.tsx file that enables page transitions with Framer-Motion and AnimatePresence. I'm unsure about how to connect this with my layout.tsx

_app.tsx

import { AnimatePresence } from "framer-motion";
import { AppProps } from "next/app";
import { useRouter } from "next/router";

export default function App({ Component, pageProps }: AppProps) {
  const router = useRouter();
  const pageKey = router.asPath;

  return (
    <div>
      <AnimatePresence initial={false} mode="popLayout">
        <div className="flex flex-col min-h-screen">{pageKey}</div>
        <Component key={pageKey} {...pageProps} />
      </AnimatePresence>
    </div>
  );
}

layout.tsx

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "@/components/layout/header";
import Lines from "@/components/line/lines";
import Footer from "@/components/layout/footer";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "A website for gamers",
  description: "A website for gamers is a website for gamers.",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <main className="min-h-screen grid grid-rows-[auto,1fr,auto]">
          <Header />
          <div className="relative overflow-hidden">
            <Lines />
            {children}
          </div>
          <Footer />
        </main>
      </body>
    </html>
  );
}

PageTransisiton

import React, { forwardRef, useMemo } from "react";
import { motion, HTMLMotionProps, AnimatePresence } from "framer-motion";

type PageTransitionProps = HTMLMotionProps<"div">;
type PageTransitionRef = React.ForwardedRef<HTMLDivElement>;

function PageTransition(
  { children, ...rest }: PageTransitionProps,
  ref: PageTransitionRef
) {
  const fromTheBottom = { y: "100%" };
  const inTheMiddle = { y: 0 };
  const toTheTop = { y: "-100%" };

  const transition = { duration: 0.6, ease: "easeInOut" };

  return (
    
      <motion.section
        className="relative flex-1 h-full flex flex-col"
        ref={ref}
        initial={fromTheBottom}
        animate={inTheMiddle}
        exit={toTheTop}
        transition={transition}
        {...rest}
      >
        {children}
      </motion.section>
  );
}

export default forwardRef(PageTransition);

Page.tsx

"use client";

import Hero from "@/components/hero/hero";
import PageTransition from "@/components/pageTransition";
import { forwardRef } from "react";

type IndexPageProps = {};
type IndexPageRef = React.ForwardedRef<HTMLDivElement>;

function IndexPage(props: IndexPageProps, ref: IndexPageRef) {
  return (
    <PageTransition ref={ref}>
      <Hero />
    </PageTransition>
  );
}

export default forwardRef(IndexPage);
1

There are 1 best solutions below

0
Celestius On

I'm not entirely sure if I understand your question correctly.

Why are your using page transitions with Framer Motion and AnimatePresence in the first place?

Page routing in Next.js 13 remains similar to the previous versions.

In previous versions, you would define pages like this:
In the "pages" folder you would define the pages:

  • pages/home.tsx => //https:www.mydomain.com/home
  • pages/about.tsx => //https:www.mydomain.com/about

With the app router in Next.js 13, the structure is slightly different.
You create a folder with the name of your page in the "app" folder, and within that folder, you create a page.tsx file. For example:

  • app/home/page.tsx => //https:www.mydomain.com/home
  • app/about/page.tsx => //https:www.mydomain.com/about

The layout.tsx file is optional and is intended for UI components shared between routes.

Here is the official documentation for the file conventionsin next 13.
https://nextjs.org/docs/app/api-reference/file-conventions