node.jsnext.jsglidejs

Using Glide JS with Next.js: document is not defined


I've created a plain HTML webiste with a carousel using Glide JS. Then I moved to Next JS and I'm stucked with a "ReferenceError: document is not defined" related to the script I use to run the carousel. I am aware about Node not having DOM, but still I don't know what to do to fix this.

The error here:

Server Error
ReferenceError: document is not defined

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
components/Glide.js (3:14) @ document

  1 | import Glide from '@glidejs/glide'
  2 | 
> 3 | let sliders = document.querySelectorAll('.glide');
    |          ^
  4 | for (let i = 0; i < sliders.length; i++) {
  5 |     let glide = new Glide(sliders[i], {
  6 |         startAt: 0,

This is my code:

components/Glide.js

import Glide from '@glidejs/glide'

let sliders = document.querySelectorAll('.glide');
    for (let i = 0; i < sliders.length; i++) {
        let glide = new Glide(sliders[i], {
            startAt: 0,
            autoplay: 2800,
            hoverpause: true,
        });
        glide.mount();
    }

pages/index.js (relevant part)

import Glide from "./components/Glide"

export default function Home() {
    return(
        <>
<div className="glide-container">
    <div className="glide">
        <div data-glide-el="controls" >
            <button data-glide-dir="<" className="glide__arrow glide__arrow--left">`{'<'}`</button>
            <button data-glide-dir=">" className="glide__arrow glide__arrow--right">`{'>'}`</button>
        </div>
        <div className="glide__track" data-glide-el="track">
            <ul className="glide__slides">

                <li className="glide__slide"><img src="1.jpg" />1</li>
                <li className="glide__slide"><img src="2.png" />2</li>
                <li className="glide__slide"><img src="3.png" />3</li>
                <li className="glide__slide"><img src="4.png" />4</li>
            </ul>
        </div>

        <div className="glide__bullets" data-glide-el="controls[nav]">
            
            <button className="glide__bullet" data-glide-dir="=0"></button>
            <button className="glide__bullet" data-glide-dir="=1"></button>
            <button className="glide__bullet" data-glide-dir="=2"></button>
            <button className="glide__bullet" data-glide-dir="=3"></button>

        </div>
    </div>
</div>

 
        </>
  )
}

To reproduce the error:

  1. Create a new nextJS project by running npx create-next-app@latest and using this configuration:
  1. Install GlideJS by running npm install @glidejs/glide
  2. Create the two files described above.
  3. run npm run dev

I tried looking at here: How to use Glide js in Next js

And here: Next.js: document is not defined

But still, I can't figure out what I should do.


Solution

  • This is what I did and worked:

    1. Deleted Glide.js component (see question description)
    2. Replaced the original glide-container div and everything inside at pages/index.js (relevant part) (see question description) with a <GlideContainer /> tag
    3. Created GlideContainer.js component as you can see below:
    import React, { useLayoutEffect } from "react";
    import Glide from '@glidejs/glide';
    
    export default function GlideContainer() {
        useLayoutEffect(() => {
           let sliders = document.querySelectorAll('.glide');
        for (let i = 0; i < sliders.length; i++) {
            let glide = new Glide(sliders[i], {
                startAt: 0,
                autoplay: 2800,
                hoverpause: true,
            });
            glide.mount();
        }
    
        })
    
        return(
            <>
                <div className="glide-container">
                    <div className="glide">
                        <div data-glide-el="controls" >
                            <button data-glide-dir="<" className="glide__arrow glide__arrow--left">{'<'}</button>
                            <button data-glide-dir=">" className="glide__arrow glide__arrow--right">{'>'}</button>
                        </div>
                        <div className="glide__track" data-glide-el="track">
                            <ul className="glide__slides">
    
                                <li className="glide__slide"><img src="img/PastEvents/9.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/10.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/11.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/12.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/13.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/14.jpg" /></li>
                                <li className="glide__slide"><img src="img/PastEvents/15.jpg" /></li>
                                
                            </ul>
                        </div>
    
                        <div className="glide__bullets" data-glide-el="controls[nav]">
                            
                            <button className="glide__bullet" data-glide-dir="=0"></button>
                            <button className="glide__bullet" data-glide-dir="=1"></button>
                            <button className="glide__bullet" data-glide-dir="=2"></button>
                            <button className="glide__bullet" data-glide-dir="=3"></button>
                            <button className="glide__bullet" data-glide-dir="=4"></button>
                            <button className="glide__bullet" data-glide-dir="=5"></button>
                            <button className="glide__bullet" data-glide-dir="=6"></button>
                            <button className="glide__bullet" data-glide-dir="=7"></button>
                        </div>
                    </div>
                </div>
            </>)}