What is the best way to implement smooth scrolling to an anchor tag from a different page in NextJS?

In my NextJS project, I have two main pages - the Home page and the Leaderboard page. The navigation bar code looks like this:

<div className={styles.navItem}>
        <Link href="/">
          <a className={styles.navLinks} onClick={toggle}>
            Home
          </a>
        </Link>
      </div>
      <div className={styles.navItem} onClick={toggle}>
        <Link href="/">
          <a
            className={styles.navLinks}
            onClick={setTimeout((e) => {
              document.getElementById("about") &&
                document
                  .getElementById("about")
                  .scrollIntoView({ behavior: "smooth", block: "end" });
            }, 2000)}
          >
            About Us
          </a>
        </Link>
      </div>
      <div className={styles.navItem} onClick={toggle}>
        <Link href="/">
          <a
            className={styles.navLinks}
            onClick={setTimeout((e) => {
              document.getElementById("program") &&
                document
                  .getElementById("program")
                  .scrollIntoView({ behavior: "smooth", block: "end" });
            }, 2000)}
          >
            Program Overview
          </a>
        </Link>
      </div>
      <div className={styles.navItem}>
        <Link href="/leaderboard/">
          <a className={styles.navLinks} onClick={toggle}>
            Leaderboard
          </a>
        </Link>
      </div>

I tried using a delay with setTimeout to ensure that when clicking on a link in the navbar, it would first take me to the homepage and then smoothly scroll to the desired section after 2 seconds. However, I encountered an error saying document is not defined. Additionally, upon reloading the page, it automatically smooth-scrolls to #program without any interaction. How can I resolve this issue?

ERROR (ON TERMINIAL)

error - components/main/Nav/MenuRight.js (18:23) @ Timeout.eval [as _onTimeout]
ReferenceError: document is not defined
  16 |         <Link href="/">
  17 |           <a
> 18 |             className={styles.navLinks}
     |                       ^
  19 |             onClick={() =>
  20 |               setTimeout((e) => {
  21 |                 document.getElementById("about") &&

Answer №1

One issue is that you are directly calling setTimeout, which executes immediately on the server (specifically, NextJS does not have access to the window and document objects on the server-side). This is why document is not available.

To fix this, wrap it in a function as shown below so that the onClick event only triggers when the element is clicked:

<div className={styles.navItem}>
        <Link href="/">
          <a className={styles.navLinks} onClick={toggle}>
            Home
          </a>
        </Link>
      </div>
      <div className={styles.navItem} onClick={toggle}>
        <Link href="/">
          <a
            className={styles.navLinks}
            onClick={(e) => {
             setTimeout(() => {
              document.getElementById("about") && document.getElementById("about").scrollIntoView({ behavior: "smooth", block: "end" });
            }, 2000)
            }}
          >
            About Us
          </a>
        </Link>
      </div>
      <div className={styles.navItem} onClick={toggle}>
        <Link href="/leaderboard/">
          <a className={styles.navLinks} onClick={toggle}>
            Leaderboard
          </a>
        </Link>
      </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way for me to personalize the background of the mui-material datagrid header?

I am looking to update the background design of Mui Datagrid from this image to this image However, I am encountering an issue where the background color does not fully cover the header. I have attempted using "cellClassName:" in the columns but it has n ...

What is the reasoning behind the "open in a new tab" function triggering a GET request?

Check out this HTML tag: <a href="#" id="navBar_navBarInput_3_subNavDropdownInput_0_subNavLinkInput_0" onclick="redirectPost(4,'EntryData.aspx');">My Cool Link</a> The Javascript function "redirectPost" function redirectPost(id, ur ...

Every time I try to request something on my localhost, NextJS console throws a TypeError, saying it cannot read the properties of undefined, specifically '_owner'

Update: I've noticed that these errors only appear in Chrome, while other browsers do not show them. Recently, I created a simple NextJS project by following a couple of tutorials, which also includes TypeScript. However, after running npm run dev, I ...

Determine the current position of the cursor within a contenteditable division

I came across this code snippet on a forum to determine the cursor position in a contenteditable div, but unfortunately it consistently returns 0. Here is the function responsible for retrieving the cursor position: new function($) { $.fn.getCursorPo ...

How can I stretch a background image using jquery to cover the entire document instead of just the window

I have implemented a plugin called https://github.com/srobbin/jquery-backstretch to effectively stretch the background image. The problem arises when the content of the page is long enough to create a scrollbar. In this case, while scrolling, the backgrou ...

Running a function exclusively within a single div using Angular 2

I am currently using *ngFor to group items, and it's functioning correctly. However, I am having trouble displaying the "listofGroup" in the view even though it works in the console. Specifically, I need to run a function within a specific div in Angu ...

Using JQuery and CSS to handle multiple hyperlink links with a single action

UPDATE: Issue resolved, thanks for the help. It is working fine now: http://jsfiddle.net/c3AeN/1/ by Sudharsan I have multiple links on my webpage, all in a similar format like this: note: When I say 'similar format', I mean that all links share ...

Styling an input text using CSS and Jquery without relying on a parent

Styling CSS input text without a parent div Hello everyone, I am looking to remove the <div id="input_container"> from the code below. Is it possible to achieve the same result without that surrounding div? Check out the jsfiddle: http://jsfiddle.n ...

However, when it comes to the jQuery dropdown menu, the submenus open inwards rather than extending

I recently developed a jQuery menu that includes dropdowns. However, I encountered an issue where the subMenu items do not open to the left when hovered over. Despite my attempts to adjust the position using CSS properties such as absolute or relative posi ...

Invoking a method in Vue.js from another component

I'm just starting out with VUE and I have a unique challenge for my project. I want to have a button on one page that triggers a function on another page. I know some may ask why not keep the button and function on the same page, but I am exploring ho ...

Accessing Cognito using ReactJS and fetching data with specific parameters

I'm currently attempting to retrieve the email of the user who is logged in and use it within my fetch() call. I have successfully obtained the email using getfirstapi() and used it in my form, but I am encountering issues when trying to pass it into ...

What are some alternatives to tables for displaying two lines of headings and corresponding data?

Here is a snippet of HTML code I am working with: <div><span class='top'>Answered</span></div><div id="hour">15</div> <div><span class='top'>Not Answered</span></div ...

Error: Node application using Express does not display 'Server Started' message in console upon execution

I'm encountering an issue where I don't see the "Server Start: 3001" message on the console when I run 'node app.js' in the terminal. Below is the content of my app.js file: var createError = require('http-errors'); var exp ...

Guide on integrating msw with Next.js version 13.2.1 (Issue: Unable to access worker.start on the server)

I'm currently in the process of integrating a simulated API that sends back a response object containing a series of messages meant to be displayed in the UI (specifically, a chatbox) alongside the username, user picture, and other relevant informatio ...

Changing the color of the timePicker clock in material-ui: a step-by-step guide

I have been attempting to update the color of the time clock in my timeInput component (material-ui-time-picker) for material-ui, but unfortunately, it is not reflecting the change. Here is the code I am using: <TimeInput style ={heure} ...

Get information within nextjs application router edge functions

I've been working on setting up the Next.js app router and have created an api folder within the app directory, specifically at app/api/route.ts. Below is a snippet of the code found in that route.ts file. export async function POST(request: Request) ...

Getting to a different page while not maintaining scroll position using React

I'm currently working on a project using Next/React. I encountered an issue where, upon clicking a button that is supposed to navigate to another page, the scroll position is retained, causing the new page to load with the content X pixels down from t ...

Changing table data using a switch in mui-datatables when my information is stored as boolean values

How can I update my boolean data in a Switch component for each row fetched from Firestore? The data is currently being displayed correctly, but when I click on the Switch to change it from true to false or vice versa, nothing happens. Can someone help me ...

Creating Unique Identifiers in ExpressJS

I am currently utilizing mongoose to display admin and user information on a dashboard, but I am encountering difficulty rendering the id of a user. Below is the code I am using: function ensureAuthenticated(req, res, next){ if(req.isAuthenticated()){ ...

Tips on changing the URL of the current tab after clicking on a link

const selenium = require('selenium-webdriver'); require('chromedriver'); const By = selenium.By; const driver = new selenium.Builder().forBrowser('chrome').build(); const url = 'https://example.com'; driver.get(url) ...