snipcart / next-snipcart-store

40 stars 34 forks source link

Cannot go back to initial landing page using browser back button #1

Open talhaguy opened 3 years ago

talhaguy commented 3 years ago

Hello!

I've been facing a browser navigation issue with the Snipcart script in a NextJS project. I created a minimal reproduction fork here: https://github.com/talhaguy/next-snipcart-store. The issue is as follows:

Replication Steps

  1. Go to home page
  2. Click on FAQ page link in nav
  3. Once FAQ page is loaded, press browser back button

Expected Page should go back again.

Actual Page visually remains on the same one. The URL does change though.

After some debugging, I noticed the history state object is a little different on the landing page with and without Snipcart.

history.state with Snipcart: with-snipcart

history.state without Snipcart: wo-snipcart

I created a branch in the reproduction repo with a fix by replacing the landing page history state: https://github.com/talhaguy/next-snipcart-store/tree/fix. I am using the NextJS router to accomplish this:

// _app.js

import { useEffect } from 'react';
import { useRouter } from 'next/router'

function useResetHistory() {
  const router = useRouter()

  useEffect(() => {
    document.addEventListener("snipcart.ready", () => {
      Snipcart.events.on('snipcart.initialized', (snipcartState) => {
        router.replace(router.pathname)
      });
    });
  }, [])
}

function MyApp({ Component, pageProps }) {
  useResetHistory()

  return <Component {...pageProps} />
}

export default MyApp

Although it does seem to be working fine now, it feels hacky. Is there a better way to handle this? Is this truly a conflict between NextJS routing and Snipcart routing?

Thank you, Muhammad Talha

colbyfayock commented 3 years ago

hey @talhaguy i was able to reproduce as well, I'll see what i can find out

talhaguy commented 3 years ago

Thanks, @colbyfayock - Just adding on here that I had to update the useResetHistory hook with the following since it was breaking on pages with dynamic slugs:

function useResetHistory() {
  const router = useRouter()

  useEffect(() => {
    document.addEventListener("snipcart.ready", () => {
      Snipcart.events.on('snipcart.initialized', (snipcartState) => {
        // use `router.asPath` instead of `router.pathname`
        router.replace(router.asPath)
      });
    });
  }, [])
}