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

Troubleshooting: Why isn't my jQuery Click Event functioning in Mozilla but working perfectly fine in

While I know this question has been asked before, I can't seem to locate the posts I remember reading about it. I apologize for any duplication, but I am trying to implement a "click anywhere BUT here to close element overlay" effect on my personal we ...

Tips for displaying a table with a button click

I am struggling to figure out how to embed a table inside a button in order to display the table when the button is clicked and hide it when clicked again. Below is the code I have been working with: function toggleTable(){ document.getElementById ...

Disappearing PHP Session following a redirection

I'm encountering an issue with the LDAP Authentication redirection in my system. When I access Index.php, it correctly redirects me to the login page (login.php). However, after entering my credentials, it fails to redirect me back to the Index Page. ...

Alert: The package **react-native-sqlite-storage** has been flagged for having an incorrect configuration: The entry "**dependency.platforms.ios.project**" is not permitted

When running the command npx react-native start -- --reset-cache, I encountered a warning about the package react-native-sqlite-storage having an invalid configuration. It mentioned that "dependency.platforms.ios.project" is not allowed and advised to veri ...

Ensure that the following div remains positioned beneath the current one

After reading through this question on Stack Overflow, about creating a responsive table with both vertical and horizontal headers, I came across this particular issue, demonstrated in this codepen example: Currently, the second table appears directly bel ...

Mismatch of data types in Google Visualization

I am working with Google Visualization and receiving Unix Epoch timestamps that I need to convert into an array of strings for use in Google Charts. However, I keep encountering an error: Type mismatch. Value 2017-8-25 16:23:54,2017-8-25 16:11:54,... does ...

Can you explain the significance of the '#' symbol within the input tag?

I was reading an article about Angular 2 and came across a code snippet that uses <input type='text' #hobby>. This "#" symbol is being used to extract the value typed into the textbox without using ngModal. I am confused about what exactly ...

Protractor struggles to locate mobile values in the HTML DOM despite Selenium's capabilities

I recently encountered an issue while attempting to scrape data for mobile test cases. The code snippet below works flawlessly for desktop, but on mobile it fails to find the desired element (resulting in an empty console log). Interestingly, when I print ...

"The JavaScript code included in the index.html file is not functioning as expected when called in the main.js file within a

Here is the index.html code for a simple VueJS app that includes a widget from netvibes.com. The widget code is added in the html file and functioning properly. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC " ...

Pause the execution of an AJAX callback function after numerous AJAX requests

I have two separate Ajax calls in my code. Both of them have different callbacks that need to execute upon successful call. $.ajax({ type: 'POST', url: "url1", success: foo1 }); $.ajax({ type: 'POST', url: "url2", ...

Interface not being assigned payload by Account Reducer

I'm currently facing an issue while trying to update an interface with a reducer payload obtained from one of my context providers. As a newcomer to GraphQL and React, I admit my lack of proficiency in explaining the problem but here goes. My situati ...

Tips for enabling only a single div to expand when the "read more" button is clicked

I'm having trouble with my blog-style page where I want only one "read more" link to expand while collapsing the others. I've tried various jQuery methods and HTML structures, but haven't been able to achieve the desired result. Can someone ...

A guide to accessing the sibling of each selector with jQuery

Imagine you have the following HTML structure: <div class="parent"> <div class="child"></div> <div class="sibling">content...</div> </div> <div class="parent"> <div class="child"></div> <div ...

Is it better to use multiple external style sheets?

Hello! I am looking to implement a pop-up login screen by integrating downloaded code. The issue I am facing is that the CSS file that accompanies it clashes with my current one. Is there a way to have a specific style sheet only affect certain div tags, ...

Updating user data with Firebase cloud functions

For my e-commerce project, I am looking to utilize the Google Maps API to input the location of a user's shop. I have successfully utilized Google Cloud Functions to insert the latitude, longitude, and address data. Currently, the data can be insert ...

Iterating through records with a set of three columns in every row

I need to divide each row into 3 columns image : <div id="list-product"> <div class="row"> @foreach($products as $product) <div class="col-lg-4 col-md-4"> ...

In case the desired property is not detected in the object, opt for an alternative property

Here is an example object: Object -> Content: <h1>some html</h1> Url : A url In the code below, I am checking if a specific URL exists in the given object: var checkURLInArray = function(url, array) { for(var i in array) { ...

AngularJS does not automatically generate input elements for editing purposes

Trying to make real-time edits to an element by triggering a function on ng-click using AngularJS. My HTML code: <div class="row question">{{questions.1.name}} <a href="" class="glyphicon glyphicon-pencil" ng-click="editQuestion(questions.1.name ...

Implementing Title Attribute in Grid View Template Field

I have implemented a Grid View with a "TemplateField" that includes properties for Header Text and SortExpression set to true. Upon inspecting the browser, I noticed that it generates an anchor element with some JavaScript. How can I add a title tag to t ...

Unable to create the complete PDF file using html-pdf in a NodeJS environment

When trying to create a PDF from an HTML template, I am encountering some difficulties. While it works with static entries, I want to generate the PDF for multiple items that can vary each time. I feel like I might be overlooking something, so any suggesti ...