router.asPath different between server and front on 404 page
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT Mon Sep 5 10:15:47 UTC 2022
Binaries:
Node: 16.16.0
npm: 8.19.1
Yarn: N/A
pnpm: N/A
Relevant packages:
next: 12.3.1-canary.2
eslint-config-next: 12.3.0
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
Firefox developer edition 105.0b4 (64 bits)
How are you deploying your application? (if relevant)
No response
Describe the Bug
When accessing /someUnknownUrl
const router = useRouter();
console.log(router.asPath); // '/404' on server '/someUnknownUrl' on browser
useRouter does not work consistently between browser and server on 404 page.
Expected Behavior
router.asPath should be '/someUnknownUrl' on server too
Link to reproduction
https://stackblitz.com/edit/vercel-next-js-ycc47c?file=pages/404.tsx
To Reproduce
Go to an unknownUrl (https://vercel-next-js-ycc47c--3000.local-corp.webcontainer.io/unknownUrl)
You can see "Error: Text content does not match server-rendered HTML" caused by different rendering
Isn't this an expected behavior as stated here?
While rendering your application, there was a difference between the React tree that was pre-rendered (SSR/SSG) and the React tree that rendered during the first render in the Browser.
It was pre-rendered with 404 on the server but it changed to the current slug on the first render. The error is easily resolved when you apply the stated fix.
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
const Custom404 = () => {
const router = useRouter();
const [slug, setSlug] = useState<string>();
useEffect(() => {
setSlug(router.asPath.substr(1).replace(/([A-Z])/g, ' $1'));
}, [router]);
return <main>{slug}</main>;
};
export default Custom404;
But router.asPath should return the same thing on server and client no ?
Thank you for your quickfix anyway ;)
If router.asPath is intended to return different content on server and on client this is not a bug then ... ;)
If router.asPath is intended to return different content on server and on client this is not a bug then ... ;)
I believe it is more of a side effect of pre-rendering rather than an intended effect. During pre-rendering inside the server, the router is unaware of the domain where it will be sent. It assumes its at /404 based on the filename, but it doesn't actually exists in a browser yet (its in the server, a server does not have a URL/web address).