skip to Main Content

I’m facing an issue with next/router. I made a ‘404 Page’ and set it up to send clients back to the home page router.push('/') after some 3 seconds. However, when clients return to the main page, they get an console error that looks like this:

client.js:1 Error: Abort fetching component for route: "/"
    at handleCancelled (router.js:408:27)
    at Router.fetchComponent (router.js:1475:13)
    at async Router.getRouteInfo (router.js:1182:50)
    at async Router.change (router.js:778:29)

Due to this error, clients can’t use <Link href="/{any_route_xyz}"> to navigate properly. In some cases, when they navigate to a page, it remains there for 3 seconds and then automatically pushes them back to the home page.

Here’s the 404.jsx code :

import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import Head from "next/head";

export default function NotFound404() {
  
  const [time, setTime] = useState(3);
  const [tick, setTick] = useState(".");
  const router = useRouter();

  useEffect(() => {
    time > 0.01 && setTimeout(() => setTime((time - 0.01).toFixed(2)), 10);
    setTimeout(() => {
      setTick(tick.length < 3 ? tick + "." : "");
    }, 300);

    setInterval(() => {
      router.push("/");
    }, 3400);
  }, [time]);

  return (
    <main>
      <Head>
        <title>Page not found</title>
      </Head>
      <div className="flex flex-col justify-center items-center h-[75vh] w-full gap-10">
        <h1 className="text-6xl italic font-bold font-mono text-center">404! NOT FOUND!!</h1>
      </div>
      <p className="font-mono italic text-center">
        Returning back in {time} seconds {tick}
      </p>
    </main>
  );
}

And here’s the code for navigation.jsx which is static component for every page:

<ul className="flex gap-14 mr-12">
  <li className="hover:underline">
    <Link href="/">Homepage</Link>
  </li>
  <li className="hover:underline">
    <Link href="/add">Add</Link>
  </li>
  <li className="hover:underline">
    <Link href="/contact">Contact</Link>
  </li>
  <li className="hover:underline">
    <Link href="/about">About</Link>
  </li>
</ul>

i tried using window.location='/' but it didn’t worked.

3

Answers


  1. Chosen as BEST ANSWER

    I make the router to execute only once when variable time is 0 (You can use a boolean flag also)

    useEffect(() => {
      time > 0 && setTimeout(() => setTime((time - 0.01).toFixed(2)), 10);
      setTimeout(() => {
        setTick(tick.length < 3 ? tick + "." : "");
      }, 300);
      time == 0 && router.replace("/");
    }, [time]);
    

  2. The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.

    https://developer.mozilla.org/en-US/docs/Web/API/setInterval

    That means router.push is called multiple times (even after the component is unmounted). That results in the error you are seeing. Refer https://github.com/vercel/next.js/discussions/39040

    So to solve this issue, you need to clear your interval before unmounting.

    useEffect(() => {
        time > 0.01 && setTimeout(() => setTime((time - 0.01).toFixed(2)), 10);
        setTimeout(() => {
            setTick(tick.length < 3 ? tick + "." : "");
        }, 300);
    
        const interval = setInterval(() => {
            router.push("/");
        }, 3400);
    
        return () => clearInterval(interval);
    }, [time]);
    

    You can also cleanup your time function if your intention is to wait 3 seconds (and remove the setTimeout and setInterval).

    useEffect(() => {
        const fn = async () => {
            await new Promise(r => setTimeout(r, 3400));
            router.push("/");
        }
    
        fn();
    }, []);
    
    Login or Signup to reply.
  3. just use window.location.replace("/") instead of router.push("/")

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search