Enhance Your Website with GatsbyJS Custom Scrollbars

I'm struggling to customize the default scrollbar on my Gatsby website with an overlay scrollbar. I want to avoid the page 'shifting' slightly to the left when switching between pages that have scrollbars and those that do not.

My attempt involves using the package: https://www.npmjs.com/package/overlayscrollbars-react, but I can't figure out where to integrate the JSX component within Gatsby?

I've experimented by wrapping the <html> tag in src/html.js, but this approach results in a blank white page without loading any content of my website.

I've also tried wrapping elements like <body> in src/html.js and even other elements further down the HTML tree (in my own code files, e.g., index.tsx), but so far, I've had no success.

Could someone enlighten me on where exactly I should incorporate this component in GatsbyJS? I'm still trying to grasp how Gatsby structures everything.

Below is my current code snippet for displaying the new scrollbar. Unfortunately, it's only showing the default scrollbar:

index.tsx:

import * as React from "react";
    import PageBase from "./PageBase";

    export default function Home() {
        const navigation = [
            { name: "Home", href: "/", current: true },
            { name: "About", href: "/About/", current: false },
            { name: "My Work", href: "/My-Work", current: false },
            { name: "Contact Me", href: "/Contact", current: false },
        ];

        return (
            <>
                <PageBase navigation={navigation}>
                    <p>example content</p>
                </PageBase>
            </>
        );
    }

    

PageBase.tsx:

import * as React from "react";
    import NavBar from "../components/nav";
    import Footer from "../components/footer";
    import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
    import "overlayscrollbars/css/OverlayScrollbars.css";


    export default function PageBase(props: any) {
        return (
            <>
                <OverlayScrollbarsComponent>
                    <div className="flex flex-col dark:bg-zinc-800 min-h-screen">
                        <NavBar navigation={props.navigation}></NavBar>

                        <main className="flex justify-center mt-5 flex-grow overflow-hidden">
                            <div className="w-5/6 lg:w-4/6">
                                {props.children}
                                <br />
                                <br />
                            </div>
                        </main>

                        <Footer />
                    </div>
                </OverlayScrollbarsComponent>   
            </>
        );
    }

    

Thank you!

Answer №1

After extensive research, I stumbled upon a solution for this issue. I came across a codesandbox created by saurabh73 (https://codesandbox.io/s/github/saurabh73/portfolio-website/tree/master/?file=/src/components/layout/index.js:775-1094) in which he utilized React's useEffect hook to implement the scrollbar functionality.

    useEffect(() => {
        OverlayScrollbars(document.body, {
            nativeScrollbarsOverlaid: {
                initialize: true,
            },
            callbacks: {
                onInitialized: function () {
                    this.scroll(0);
                },
                onOverflowChanged: function () {
                    this.scroll(0);
                },
            },
        });
    });

I integrated this code snippet into my own PageBase component - essentially my version of a standard Gatsby Layout. Therefore, my updated PageBase now appears as follows:

PageBase.tsx:

import React, { useEffect } from "react";
import NavBar from "../components/nav";
import Footer from "../components/footer";
import "overlayscrollbars/css/OverlayScrollbars.css";
import OverlayScrollbars from "overlayscrollbars";

export default function PageBase(props: any) {
    const scrollOptions = {
        nativeScrollbarsOverlaid: {
            initialize: true,
        },
        callbacks: {
            onInitialized: function () {
                this.scroll(0);
            },
            onOverflowChanged: function () {
                this.scroll(0);
            },
        },
    };

    useEffect(() => {
        OverlayScrollbars(document.body, scrollOptions);
    });

    return (
        <>
            <div className="flex flex-col dark:bg-zinc-800 min-h-screen">
                <NavBar navigation={props.navigation}></NavBar>

                <main className="flex justify-center mt-5 flex-grow">
                    <div className="w-5/6 lg:w-4/6">
                        {props.children}
                        <br />
                        <br />
                    </div>
                </main>

                <Footer />
            </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

The most efficient method for documenting $.trigger in JavaScript/jQuery is through the use of JSD

When it comes to documenting in jsDuck, what is the optimal method for capturing the following event trigger: $(document).trigger('myCustomEvent'); ...

Encountering an issue when using both the Google Maps API and Google URL Shortener API within the same program

Recently, I developed a program that involves passing data to an iframe through a URL. However, due to the limitation of Internet Explorer supporting only 2083 characters in a URL, I decided to use the Google URL Shorten API to shorten the URL before sendi ...

Using Javascript and Node.js to send a JSON request

While browsing through this particular question, I came across a method in node.js to distinguish between html requests and json requests: app.get('/route', function (req, res) { if (req.is('json')) res.json(data); else if (req ...

Having trouble displaying Material UI components in a React application?

I have encountered an issue where the text content of Material UI components is not being rendered to the final HTML. When looking at the render method of my component, it appears as follows: render() { const panel = this.props.panel; return (< ...

Conceal a div until reaching the end of the webpage by scrolling

Currently, I am working on a web page inspired by music release pages (check out an example here). My goal is to have certain hidden divs at the bottom of the page only reveal themselves once the user has scrolled all the way down, with a delay of a few se ...

How can one eliminate the white space surrounding the data that Vue is binding?

Working with Vue, I've noticed a gap on the screen following the data binding. Instead of using Vanilla JavaScript's trim() function, is there a way to remove leading and trailing whitespace? Let me provide you with the code for the data binding ...

AngularJS: monitoring changes in an array property

For the problem at hand, take a look at this link: http://plnkr.co/edit/ZphAKvZeoVtuGFSEmOKg?p=preview Imagine you have an array structured like this: var arr = [ { 'a': "123", 'b': "654" }, { 'a': "456", &apo ...

Exploring the methods of connecting with data-checked and data-unchecked attributes in Angular

Utilizing a toggle switch, I am able to determine what text to display in the div by utilizing html attributes such as data-checked and data-unchecked. In addition, I have an Angular pipe that translates all texts on the website based on the selected lang ...

Combine various input data and store it in a variable

I am looking for a way to add multiple input text values together and store the sum in a variable. Currently, I can add the values and display it in an id, but I want to assign it to a variable instead. The condition for this variable is described below af ...

showing information from a table column

Utilizing the jQuery DataTables plugin with a JSF <h:dataTable>. The page contains 86 records. +++++++++++++++++++++++++++++++++++++ + SN. + Name + Email + +++++++++++++++++++++++++++++++++++++ + 1 + Name 1 + Email 1 + + ...

Dynamic height adjustment for Bootstrap right column

I am struggling to create a layout with a right column using bootstrap. I can't figure out how to achieve the desired arrangement shown in this image. https://i.stack.imgur.com/VaIWD.png I have attempted various methods but the right column does not ...

The Markdown-to-jsx tool is having trouble processing the provided source code

Utilizing a Material UI blog post template found at https://github.com/mui-org/material-ui/tree/master/docs/src/pages/getting-started/templates/blog, I have created my React app using npx create-react-app. Upon console logging the source, it displays as a ...

Error message: Stripe - Uncaught (in promise) IntegrationError: The value provided for stripe.confirmCardPayment is invalid

Error Alert: v3:1 Uncaught (in promise) IntegrationError: Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: . To view the error directly, visit: Steps to replicat ...

Tips for customizing the color of mat-select placeholder text?

I've been attempting to modify the color of a mat-select placeholder. It functions properly when using 'background-color' but not when using 'color'. Below is my CSS code: /deep/ .mat-select-placeholder { color: red; } .mat-s ...

The functionality of Material-ui is not performing as expected

I am a beginner with React material-ui and followed their guide to create a simple Appbar similar to theirs. However, my Appbar looks different from what I expected: Here is how my Appbar looks: https://i.stack.imgur.com/8LKEO.png It was supposed to loo ...

Omit specific object properties within a foreach loop in jQuery AJAX

Check Out This Fiddle Example I am currently working with a PHP file that returns JSON data for main content along with an additional property for pagination. I am looking for a way to exclude the pagination property when iterating over the data in a fore ...

New to using JavaScript and JQuery, attempting to position a form underneath an image at a specific URL for the

Hello, I'm having difficulties placing a form below an image with a specific URL. As someone who is still learning JQuery, I am unsure of what mistake I might be making. Is there anyone who can help me figure out what's wrong here? <html> ...

ReactJS - accessing attribute returns null

Having trouble with the getAttribute() method in my React code. const handleChange = (event) => { let selectM = event.target.getAttribute("data-minister_name"); console.log(selectM); }; <List dense sx={{ width: '10 ...

The authService is facing dependency resolution issues with the jwtService, causing a roadblock in the application's functionality

I'm puzzled by the error message I received: [Nest] 1276 - 25/04/2024 19:39:31 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AuthService (?, JwtService). Please make sure that the argument UsersService at index [0] is availab ...

A guide to showcasing tabs as a navigation menu based on media size using AngularJS

Help needed with creating a navigation menu that includes nav-icons on specific media screen sizes. The goal is to display all tabs as a list when clicking on the nav-icon. An attempt was made to implement a navbar, but it interfered with the tab styling. ...