🦁

[Next.js]カスタムエラーページ上だと実際のURLのパスと router オブジェクトの pathname が異なり得るよねって話

2023/06/08に公開
import { useRouter } from 'next/router';

...

const { pathname } = useRouter();

みたいな感じで使っている pathname って、/pages ディレクトリでのページのパス[1]で、実際のURLのパスと異なる場合ってあるよねって話です。

よくあるのが、カスタムエラーページとかで 404 のページを配信している場合、仮に pages/404.tsx で配信されているとしよう。その場合、

/not/fount/page

で配信されるページは

/404.tsx

です。

URL 上のパスは /not/fount/page ですが、ページ上の router オブジェクトの pathname で取得される値は /404 です。

そういう場合があるので、URL 上のパスを参照したい場合は window.location.pathname が参照できるが、これはクライアントサイドでないと実行できない[2]
この解決方法は色々あるが、例えば useEffect がクライアントサイドでしか実行されないのを利用して、

  const [pathName, setPathName] = useState('');

  useEffect(() => {
    setPathName(window.location.pathname);
  }, []);

みたいに書くことができたりする。

脚注
  1. https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next/router#router-オブジェクト ↩︎

  2. クライアントサイドに来ないと window オブジェクトを参照できないため ↩︎

Discussion