KingSora / OverlayScrollbars

A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
https://kingsora.github.io/OverlayScrollbars
MIT License
3.83k stars 214 forks source link

OverlayScrollbarsComponent does not render server-side #620

Closed mjawhariPT closed 6 months ago

mjawhariPT commented 6 months ago

I am trying to use overlayscrollbars-react with NextJS 13. I want to replace the scrollbar for my body element, so my code looks like this:

export default function RootLayout({ children, params: { locale } }) {
    return (
        <html lang={locale}>
            <OverlayScrollbarsComponent
                element="body"
                className={ptSans.className}
                defer
            >
                <Navbar locale={locale} />
                <div className="content">
                    {children}
                    <Footer />
                </div>
            </OverlayScrollbarsComponent>
        </html>
    );
}

However, this gives me an error telling me that the OverlayScrollbarsComponent uses a functionality that's only available to client components, despite the docs saying that this library can be run on the server:

ReactServerComponentsError:

You're importing a component that needs useImperativeHandle. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials

   ,-[/opt/playtogether/node_modules/overlayscrollbars-react/overlayscrollbars-react.mjs:1:1]
 1 | import R, { useMemo as w, useRef as f, useEffect as v, forwardRef as C, useImperativeHandle as E } from "react";
   :                                                                         ^^^^^^^^^^^^^^^^^^^
 2 | import { OverlayScrollbars as I } from "overlayscrollbars";
 3 | const O = () => {
 4 |   if (typeof window > "u") {
   `----

The error was caused by importing 'overlayscrollbars-react/overlayscrollbars-react.mjs' in './src/app/[locale]/layout.jsx'.

Maybe one of these should be marked as a client entry with "use client":
  ./src/app/[locale]/layout.jsx

Am I doing something wrong? Thanks!

KingSora commented 6 months ago

Good day @mjawhariPT :)

OverlayScrollbars is able to run on the server without problems. The problem here is the RSC expectation to run only on the server.

When using "use client" aka. Client Components in NextJs it doesn't mean that the component is runnung only on the client. It means that the component could be run on the client and on the server for server side rendering. What "use client" indicates is that the components javascript will be included in the clients bundle because it possibly could be executed there.

Now to "use server" aka. Server Conponents. This indicates that the component will be run only on the server and never on the client. With such components the javascript needed for rendering on the server will not be in included in the client bundle. This makes sense for components which are static and require no client side javascript. Since OverlayScrollbars is a javascript library which is intended to run on the client (but can also be run on the server for ssr) you'll need to use the "use client" annotation for it. This just means that the components javascript is expected to be executed also on the client and doesnt mean that the component wont run on the server.

mjawhariPT commented 6 months ago

Ah that makes sense, thank you for the thorough explanation!