score:0

I've created a query param called anchor, and with that I can control the scroll based on the useEffect.

The link: /about?anchor=capabilities

The code on the page which should have the smooth scroll:

const router = useRouter();

useEffect(()=> {
  if (router?.query?.anchor) {
    let elem = document.getElementById(router?.query?.anchor)
    if (elem) {
      elem.scrollIntoView({behavior: "smooth"});
    }
  }
}, [router?.query?.anchor])

score:1

For next.js

//https://yourdomain.com/page?scroll=scroll_here <---

import { useEffect } from 'react';
import { Flex } from '@chakra-ui/react';
import { useRouter } from 'next/router';
export default function DecisionAreaFlex(props) {
  const router = useRouter();
  useEffect(() => {
    console.log('router query', router.query.scroll);
    if (router.query.scroll) {
      let elem = document.getElementById(router.query.scroll);
      if (elem) {
        elem.scrollIntoView({ behavior: 'smooth' });
      }
    } else {
      window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
    }
  }, [router]);

  return (
    <Flex
      alignSelf="center"
      justifyContent="center"
      alignItems="center"
      mt="15px"
      id={'scroll_here'} // <--- 
    >
      {props.children}
    </Flex>
  );
}

score:3

I just add this in the index.css

html {
  scroll-behavior: smooth;
}

and this

 <ScrollLink
            className="navy"
            smooth={true}
            duration={500}
            to="projects"
          >
            projects
 </ScrollLink>

became

 <a href="/#projects">Projects</a>

this was so fast and simple and worked prefectly

score:15

If "duration" parameter isn't of great importance for you and you have no problems with Hooks, I'd like to suggest solution as follows.

  • You get rid of Scroll component and use plain Link from RR in your NavBar like so

    <Link to="/#projects">projects</Link>
    
  • Since RR v5.1 Hooks was introduced. There is useLocation hook among them. Insert that hook at the very beginning of your Projects component like so:

    function Projects() {
    const location = useLocation()
    ...
    

When you hit Link from p.1, you get new location object of the form


    location = {
        ...
        pathname:"/",
        ...
        hash: "#projects"
    }

  • Call useEffect hook after useLocation like so:

    useEffect(()=> {
            if (location.hash) {
                let elem = document.getElementById(location.hash.slice(1))
                if (elem) {
                    elem.scrollIntoView({behavior: "smooth"})
                }
            } else {
            window.scrollTo({top:0,left:0, behavior: "smooth"})
            }
    }, [location,])

And thats it. As you can see, if there is no hash in your url, your page would scroll to the top. Use [locaton,] as useEffect dependency prevents form scrolling when your page component rerenders not because of location changes.


Related Query

More Query from same tag