(hidden)mekuri
(hidden)mekuri is a package for page transition animation in Next.js. It supports both ‘wait’ and ‘sync’ modes, as well as popstate (scroll position preservation during popstate). Since animations can be set on a per-component basis, you can implement them flexibly using animation libraries such as GSAP.
$ npm i @funtech-inc/mekuri
MekuriContext
"use client"; import { usePathname } from "next/navigation"; import { MekuriContext } from "@funtech-inc/mekuri"; export const PageTransitionContext = ({ children, }: { children: React.ReactNode; }) => { const pathname = usePathname(); return ( <MekuriContext millisecond={600} scrollRestoration={{ scrollRestoration: "restore", onEnter: (pos) => { window.scrollTo({ top: pos }); }, }} mode="wait" trigger={pathname}> {children} </MekuriContext> ); };
Mekuri
"use client"; import { MekuriFreezer, Mekuri } from "@funtech-inc/mekuri"; // import { LayoutRouterContext } from "next/dist/shared/lib/app-router-context"; // Next.js ^13.5.2 〜 import { LayoutRouterContext } from "next/dist/shared/lib/app-router-context.shared-runtime"; import { usePathname } from "next/navigation"; export const PageTransitionLayout = ({ children, }: { children: React.ReactNode; }) => { const pathname = usePathname(); return ( <Mekuri> <MekuriFreezer key={pathname} routerContext={LayoutRouterContext}> {children} </MekuriFreezer> </Mekuri> ); };
Since the key cannot be obtained by changing children during app router page transition, it is necessary to import LayoutRouterContext from next and pass the context to MekuriFreezer
.
useMekuriAnimation
"use client"; import { useRef } from "react"; import { useMekuriAnimation, useMekuriDuration } from "@funtech-inc/mekuri"; export const PageTransitionAnimation = ({ children, }: { children: React.ReactNode; }) => { const ref = useRef(null); const { second } = useMekuriDuration(); useMekuriAnimation({ onEveryLeave: () => { // some event }, }); return <div ref={ref}>{children}</div>; };
You can get the duration with useMekuriDuration
.
const { second, millisecond } = useMekuriDuration();