From 9d44c40415245a4bc3dcc9a9bc26432fb5d6d2d8 Mon Sep 17 00:00:00 2001 From: jahooma Date: Fri, 14 Jan 2022 18:43:00 -0600 Subject: [PATCH] Preserve scroll on back --- web/hooks/use-preserve-scroll.ts | 41 ++++++++++++++++++++++++++++++++ web/pages/_app.tsx | 3 +++ 2 files changed, 44 insertions(+) create mode 100644 web/hooks/use-preserve-scroll.ts diff --git a/web/hooks/use-preserve-scroll.ts b/web/hooks/use-preserve-scroll.ts new file mode 100644 index 00000000..e314d11f --- /dev/null +++ b/web/hooks/use-preserve-scroll.ts @@ -0,0 +1,41 @@ +import { useRouter } from 'next/router' +import { useEffect, useRef } from 'react' + +// From: https://jak-ch-ll.medium.com/next-js-preserve-scroll-history-334cf699802a +export const usePreserveScroll = () => { + const router = useRouter() + + const scrollPositions = useRef<{ [url: string]: number }>({}) + const isBack = useRef(false) + + useEffect(() => { + router.beforePopState(() => { + isBack.current = true + return true + }) + + const onRouteChangeStart = () => { + const url = router.pathname + scrollPositions.current[url] = window.scrollY + } + + const onRouteChangeComplete = (url: any) => { + if (isBack.current && scrollPositions.current[url]) { + window.scroll({ + top: scrollPositions.current[url], + behavior: 'auto', + }) + } + + isBack.current = false + } + + router.events.on('routeChangeStart', onRouteChangeStart) + router.events.on('routeChangeComplete', onRouteChangeComplete) + + return () => { + router.events.off('routeChangeStart', onRouteChangeStart) + router.events.off('routeChangeComplete', onRouteChangeComplete) + } + }, [router]) +} diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index e464f578..b23b6c80 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -1,8 +1,11 @@ import 'tailwindcss/tailwind.css' import type { AppProps } from 'next/app' import Head from 'next/head' +import { usePreserveScroll } from '../hooks/use-preserve-scroll' function MyApp({ Component, pageProps }: AppProps) { + usePreserveScroll() + return ( <>