- read

Smooth Scroll-to-Top Button Implementation in Next.js 13

Daniel Craciun 39

Smooth Scroll-to-Top Button Implementation in Next.js 13

Daniel Craciun
Level Up Coding
Published in
3 min read7 hours ago

--

Scroll To Top Button
Scroll To Top Button

In the ever-evolving landscape of web development, user experience is paramount.

One of the subtle yet effective ways to enhance it is by providing a convenient scroll-to-top button on your website. Whether you’re a seasoned developer or just diving into Next.js 13, this article will guide you through the process of adding a smooth-scrolling button to your web application.

Elevate your site’s usability and keep your users engaged as we explore this essential feature.

Let’s get started!

Table of Contents

  • Setup Next.js 13 Project Environment
  • Dependencies Installation
  • Reusable Scroll-To-Top Component
  • Implementation Using Route Groups

Setup Next.js 13 Project Environment

To setup a Next.js project, please check out the instructions here. The installation process generally consists of running the following command in the terminal.

npx create-next-app@latest

Dependencies Installation

Open a terminal within your project directory, and execute one of the following commands to get started:

# NOTE: you can use an icons library 
# of your choice, I personally like
# 'lucide-react'
npm install lucide-react
yarn add lucide-react
pnpm add lucide-react

Reusable Scroll-To-Top Component

While this component works in Next.js 13 applications, it can also be used in basic React or even pure HTML, CSS, JS applications.

  1. At the same level as the app/ directory, create a folder called components/ with a file called ScrollToTopButton.tsx.
  2. Inside ScrollToTopButton.tsx, copy the following code:
"use client"

import { useEffect, useState } from "react"
import { ChevronUp } from "lucide-react"

const ScrollToTopButton = () => {
const [isVisible, setIsVisible] = useState(false)

useEffect(() => {
const toggleVisibility = () => {
// if the user scrolls down, show the button
window.scrollY > 500 ? setIsVisible(true) : setIsVisible(false)
}
// listen for scroll events
window.addEventListener("scroll", toggleVisibility)

// clear the listener on component unmount
return () => {
window.removeEventListener("scroll", toggleVisibility)
}
}, [])

// handles the animation when scrolling to the top
const scrollToTop = () => {
isVisible &&
window.scrollTo({
top: 0,
behavior: "auto",
})
}

return (
<button
className={`fixed bottom-4 right-4 rounded-full p-2 outline-none transition-opacity duration-200 ${
isVisible ? "opacity-100" : "opacity-0"
}`}
onClick={scrollToTop}
>
<ChevronUp />
</button>
)
}

export default ScrollToTopButton
  • We first define a simple Boolean state isVisible that tracks whether the button should be displayed or not.
  • Upon component mount (inside the useEffect), we initialize the "scroll" event listener with the toggleVisibility function being called for every scroll event.
  • toggleVisibilty will show the button once the user scrolls 500 pixels beneath the top of the screen, and hide it otherwise.
  • The scrollToTop function is called when the button is pressed and visible, which causes a smooth transition to the top of the page.

Implementation Using Route Groups

Now that our component is ready, we need to implement this in our Next.js 13 layouts.

  1. Keep your Root Layout.tsx file as simple as possible, here is my example:
import type { Metadata } from "next"

import "path/to/globals.css"

export const metadata: Metadata = {
// ...
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className="flex min-h-screen flex-col">
{children}
</body>
</html>
)
}

2. Create a new folder inside the app/ directory called (Navigation)/ consisting of a file called layout.tsx; Here is the folder structure: app/(Navigation)/layout.tsx.

3. Inside layout.tsx, copy the following code:

import ScrollToTopButton from "@/components/ScrollToTopButton"

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<main>{children}</main>
<ScrollToTopButton />
</>
)
}

Conclusion

Congrats! Now the ScrollToTopButton is available for any web page under the (Navigation) route group.

For example, (Navigation)/scroll/page.tsx will utilize this layout and hence display the ScrollToTopButton.

If you enjoyed this article, check out my profile for many more stories like this, and stay tuned for future articles! 👍

Further Reading 📖