How To Scroll To An HTML Element In NextJS?

NextJS has various features that enable smooth scrolling to HTML elements. One method involves using useRef to create a reference to the target element and scrollIntoView to achieve smooth scrolling. Another method, using useEffect and window.scrollBy, sets up an event listener on a button for smooth scrolling when clicked, with useRef hooks to reference elements.

Prerequisites

Below are the approaches to scroll to an HTML element in NextJS:

Table of Content

  • Using ref and scrollIntoView
  • Using useEffect and window.scrollBy

Steps to Setup a NextJS App

Step 1: Create a NextJS application using the following command and answer a few questions.

npx create-next-app@latest app_name

Step 2: It will ask you some questions, so choose as the following.

√ Would you like to use TypeScript? ... No
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... No
√ Would you like to use `src/` directory? ... Yes
√ Would you like to use App Router? ... Yes
√ Would you like to customize the default import alias (@/*)? ... No

Step 3: After creating your project folder, move to it using the following command.

cd app_name

Project Structure

The updated dependencies in package.json file will look like:

  "dependencies": {
"next": "13.5.6",
"react": "^18",
"react-dom": "^18"
},

Using ref and scrollIntoView

In this approach, we are using the useRef hook to create a reference to the target element and the scrollIntoView method to smoothly scroll to this element. When the button is clicked, the scrollToElement function is triggered, causing the page to scroll to the element referenced by w3wikiRef.

Example: The below example demonstrates the scolling to an HTML element using ref and scrollIntoView.

JavaScript
// page.js this is the entry point of application

"use client";
import { useRef } from 'react';
const App = () => {
  const w3wikiRef = useRef(null);
  const scrollToElement = () => {
    if (w3wikiRef.current) {
      w3wikiRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  };
  return (
    <div style={{ padding: '20px' }}>
      <h3>Approach 1: Using ref and scrollIntoView</h3>
      <button onClick={scrollToElement}
                style={{ marginBottom: '20px' }}>
        Scroll to w3wiki
      </button>
      <div style={{ height: '100vh' }}></div>
      <h1 ref={w3wikiRef} 
          style={{ color: 'green' }}>
        w3wiki
      </h1>
    </div>
  );
};
export default App;

Start your application using the following command.

npm run dev

Output:

Using useEffect and window.scrollBy

In this approach, we are using useEffect to set up an event listener on the button, which triggers window.scrollBy to smoothly scroll to the target element when clicked. The useRef hooks are used to reference both the button and the target element.

Example: The below example demonstrates the scolling to an HTML element using useEffect and window.scrollBy.

JavaScript
// page.js this is the entry point of application

"use client";
import { useEffect, useRef } from 'react';

const App = () => {
  const targetRef = useRef(null);
  const buttonRef = useRef(null);

  useEffect(() => {
    const handleScroll = () => {
      if (buttonRef.current) {
        buttonRef.current.addEventListener('click', () => {
          window.scrollBy({
            top: targetRef.current.getBoundingClientRect().top - window.pageYOffset,
            left: 0,
            behavior: 'smooth',
          });
        });
      }
    };

    handleScroll();

    return () => {
      if (buttonRef.current) {
        buttonRef.current.removeEventListener('click', handleScroll);
      }
    };
  }, []);

  return (
    <div style={{ padding: '20px' }}>
      <h1 style={{ color: 'green' }}>w3wiki</h1>
      <h3>Approach 2: Using useEffect and window.scrollBy</h3>
      <button ref={buttonRef} 
                style={{ marginBottom: '20px', padding: '10px' }}>
          Scroll to w3wiki Courses
       </button>
      <div style={{ height: '1000px' }}>
          Scroll Down to see the 
          w3wiki Courses section
       </div>
      <div ref={targetRef} 
          style={{ height: '200px',
                   background: 'lightblue' }}>
        <h2>w3wiki Courses</h2>
        <ul>
          <li>Data Structures and Algorithms</li>
          <li>Full Stack Development</li>
          <li>Machine Learning</li>
          <li>Web Development</li>
          <li>System Design</li>
        </ul>
      </div>
    </div>
  );
};

export default App;

Start your application using the following command.

npm run dev

Output: