https://why-router-is-updated.vercel.app/
// page/index.js
function Home() {
const router = useRouter();
// alert if router is updated or init
useEffect(() => {
alert("router is updated(or init)");
console.log("router is updated(or init)", router);
}, [router]);
// alert if page is restored from bfcache
useEffect(() => {
const checkBfcache = (e) => {
console.log("This page is restored from bfcache?", e.persisted);
if (e.persisted) {
alert("This page is served from bfcache");
}
};
window.addEventListener("pageshow", checkBfcache);
}, []);
return (
<>
<Head>
<title>Create Next App</title>
</Head>
<div>
<h1>Currennt path: {router.asPath}</h1>
<div>
<h3>Inner links</h3>
<ul>
<li>
<button onClick={() => router.replace("/?a=b")}>/?a=b</button>
</li>
<li>
<button onClick={() => router.replace("/?a=b&c=d")}>
/?a=b&c=d
</button>
</li>
<li>
<button onClick={() => router.replace("/")}>/</button>
</li>
</ul>
<h3>Outer links</h3>
<ul>
<li>
<Link as="a" href="https://www.google.com" passHref={true}>
<button>https://www.google.com</button>
</Link>
</li>
</ul>
</div>
</div>
</>
);
}
// prevent '/' be static page (running as dynamic page)
Home.getInitialProps = async ({ req, res }) => {
res?.setHeader("Cache-Control", "private, no-cache, must-revalidate");
return {};
};
export default Home;
- enter page. (/)
- click
/?a=b
button. - click
/?a=b&c=d
button. - click
www.google.com(Outer link)
button. - click back button.
- bfcache is used. (page is restored without reload page)
- but router is updated, and
useEffect(()=> {...}, [router])
is triggered.- page is restored from bfcache, thus router must be not updated. but router is updated, and effect is executed.
- This bug is only generated from desktop/mobile safari, mobile chrome. (not generated from desktop chrome)
- when page is restored from bfcache, router is not updated. (not showed router update message alert)
- same as mobile safari, mobile chrome.
- but diffrent from desktop chrome...
Phase 7 is unexpected behavior. (desktop/mobile safari and mobile chrome behavior is different from desktop chrome)
And also, in below situation, router is not updated on all browsers.
- enter page. (/)
- click
www.google.com(Outer link)
button. - click back button.
- bfcache is used (page is restored without reload page)
- (important) router is not updated on all browser.
- so
useEffect(()=> {...}, [router])
is not triggered.
- so
- when page is restored from bfcache, router is not updated. (not showed router update message alert)
- In this case, same as mobile safari, mobile chrome.