0

I want to do smooth scroll with router hash but next js don't understand it. I use this function

export const scrollTo = (id: string) => {
    const element = document.getElementById(id);

    if (element) {
        window.scrollTo({
            top: element.getBoundingClientRect().top + window.scrollY,
            left: 0,
            behavior: 'smooth',
        });
    }
};

But when I use it I need to disable router push,

import Link from 'next/link';
import React from 'react';
import _ from 'lodash';
import useAppRouter from '../../../hooks/useAppRouter';

interface INavigation {
    links: string[];
}

const Navigation: React.FC<INavigation> = ({ links }) => {
    const router = useAppRouter();

    const handleCLick = (e,link) =>{
        e.preventDefault();
        scrollTo(link)
    }

    return (
        <section className="stories-navigation">
            <ul>
                {links.map((link: string) => (
                    <Link href={`#${link}`} key={link}>
                        <li>
                            <a onClick={e => handleCLick(e, link)} className={router.hash === link ? 'active-link' : ''}>
                                {_.capitalize(link)}
                            </a>
                        </li>
                    </Link>
                ))}
            </ul>
        </section>
    );
};

export default Navigation;

But I also need to show this #hashlink, but when I use and next js don't understand scrollTo function and scroll imadiatly without smooth

  • I hope that this answer can help you. [Here i use next/router events](https://stackoverflow.com/questions/69825670/smooth-scroll-in-next-js/73910056#73910056) – Edgar Vardanyan Sep 30 '22 at 14:39

1 Answers1

0

Here helper callback functions for next/router events. It works globally for next js.

export const smoothScroll = () => {
  const html = document.querySelector('html');
  if (html) {
    html.style.scrollBehavior = 'smooth';
  }
};
export const removeSmoothScroll = () => {
    const html = document.querySelector('html');
   if (html) {
       setTimeout(() => {
           html.style.scrollBehavior = 'unset';
       }, 0);
   }
};

And use this events above App component

Router.events.on('hashChangeStart', smoothScroll);
Router.events.on('hashChangeComplete', removeSmoothScroll);