4

I have a custom 404 page in my Next.JS app (404.js). On the page, I'd like to display a message like The route <strong>/not-a-route</strong> does not exist, however when using Next.js's useRouter() and router.pathname, the router thinks I'm on /404 and instead displays The route <strong>/404</strong> does not exist. How do I access the actual route I'm on in a custom 404 page?

export const NotFound: React.FC = () => {
  const router = useRouter();
  console.log(router.pathname) // prints /404
  return (
    <Layout title='Oops! Something went wrong!'>
      <div className={styles.container}>
        <h1>Oops! Something went wrong!</h1>
          <p>
            The route <strong>{router.pathname}</strong> does not exist.
          </p>
      </div>
    </Layout>
  );
};
James Whiteley
  • 3,363
  • 1
  • 19
  • 46
  • Well you are actually on `/404`. Can you show us where do you do the redirect? You can pass the route name as `props` to the `404 page ` – Sinan Yaman Apr 05 '21 at 12:00
  • @SinanYaman if the user accidentally navigates to `/abouts` instead of `/about`, the text on the page currently displays `/404` even though the browser URL is still `/abouts` - this is the scenario I'm currently trying to account for; it's not caused by a dodgy redirect. – James Whiteley Apr 05 '21 at 12:06

3 Answers3

4

You can access the redirected route as router.asPath. Try:

import {useRouter} from 'next/router'
export const NotFound: React.FC = () => {
  const router = useRouter();
  console.log(router.asPath)
  return (
    <Layout title='Oops! Something went wrong!'>
      <div className={styles.container}>
        <h1>Oops! Something went wrong!</h1>
          <p>
            The route <strong>{router.asPath}</strong> does not exist.
          </p>
      </div>
    </Layout>
  );
};
Sinan Yaman
  • 5,714
  • 2
  • 15
  • 35
  • 1
    Works, but only client side. Server result will be `asPath: "/404"` - that will result in a warning: "...did not match. Server ..." – klabak May 04 '22 at 16:22
2

You can access the original route by accessing router.asPath, where router is returned from useRouter() hook. Beware though, if you don't specify getStaticProps, router.asPath will return "/404" on server side, causing hydration error.

So to make use of router.asPath you will have to create getStaticProps function that doesn't return anything

import { useRouter } from 'next/router';

import type { GetStaticProps } from 'next';

type Props = Record<string, never>;

export const getStaticProps: GetStaticProps<Props> = () => {
  return { props: {} };
};

export default function PageNotFound() {
  const router = useRouter();

  return (
    <p>
      The requested page <strong>{router.asPath}</strong> could not be found.
    </p>
  );
}

Wojciech Maj
  • 982
  • 6
  • 21
1

Old question but just adding onto this if you're using Next.js 13

Instead of using router.asPath, you need to import usePathname from next/navigation

Eg.

'use client';

import { usePathname } from 'next/navigation';

const NotFoundPage = (): JSX.Element => {
    return (
        <div>
           {usePathname()} not found
        </div>
    );
};

export default NotFoundPage;
ffx292
  • 542
  • 12
  • 27