Mintee
Mintee

Reputation: 855

How to fix Next.js error "cancel rendering route"?

I'm trying to link to a div id and I get this error: Error: Cancel rendering route

This seems to be a problem with double linking.

I'm already using useRouter to push to a [slug], since NextLink and <a> don't cause a re-render in the map loop, which I'm using to render the content that matches(endsWith) with asPath: /posts/post-id/the-slug

  const router = useRouter();
  const { asPath } = useRouter();
  const {
    query: { id },
  } = useRouter();

  const handleHref = (link) => {
    router.push(link);
  };

This works, link to slugs that also re-renders the map loop.

  <ButtonLink
    onClick={() =>
      handleHref(
        `/posts/${id}/${String(item.slug).replace(/ /g, "-")}`
      )
    }
  >
    Example
  </ButtonLink>

Now when trying to link to a div id /posts/post-id/the-slug#div-id using the same method with useRouter or NextLink, I get the error.

  <Link href={`#${String(sect.section).replace(/ /g, "-")}`} passHref>
    <a>
      <Text>Example</Text>
    </a>
  </Link>

  //or

  <ButtonLink
    onClick={() =>
      handleHref(`/posts/${id}/${String(
        item.slug
      ).replace(/ /g, "-")}#${String(
        sect.section
      ).replace(/ /g, "-")}`)
    }
  >
    Example
  </ButtonLink>

Edit: After the first click on one of the ButtonLink in the map loop, I can't push new hash from the others.

<div>
  <ButtonLink
    onClick={() =>
      handleHref(`/posts/${id}/${String(item.slug).replace(/ /g, "-")}`)
    }
  >
    Example
  </ButtonLink>
    
  {posts.map((item) => {
    if (
      asPath.startsWith(
        `/posts/${id}/${String(item.slug).replace(/ /g, "-")}`
      )
    )
      return (
        <div key={item.id}>
          <div>
            {item.section.map((sect) => {
              <div key={sect.id}>
                <ButtonLink
                  onClick={() =>
                    handleHref(
                      `#${String(sect.section).replace(/ /g, "-")}`
                    )
                  }
                >
                  {sect.name}
                </ButtonLink>
              </div>;
            })}
          </div>
        </div>
      );
  })}
</div>

Upvotes: 12

Views: 8018

Answers (2)

Tushar Sharma
Tushar Sharma

Reputation: 145

I was also facing this same error. My old code (didn't work).

router.push('/');
router.push('#id'));

The top solution to this question using e.preventDefault() din't work either.

Then I realised that it returns a promise. You'll have to use then to resolve it.

This below one works!!

router.push('/').then(() => router.push('#id'));

Upvotes: 0

Ad&#225;n Escobar
Ad&#225;n Escobar

Reputation: 4783

I'm getting the same error using Link like this:

 const onSignOut = (event:any) => {
    auth.signout();
 }
 ...
 <Link href='#'  onClick={onSignOut} 

auth.signout() do an implicit router.push('/login')

I think in my case the error is getting because it is trying to route to # and /login at the same time.

My solution was add a preventDefault to click handler:

const onSignOut = (event:any) => {
    event.preventDefault();
    auth.signout();
}

Upvotes: 3

Related Questions