Reputation: 33
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:
npx create-next-app@latest
and using this configuration:src/
directory? Nonpm install @glidejs/glide
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.
Upvotes: 0
Views: 463
Reputation: 33
This is what I did and worked:
<GlideContainer />
tagimport 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>
</>)}
Upvotes: 0
Reputation: 853
NextJS works by hydrating prerendered HTML. NextJS generates HTML and js code on the server and then hands those to the browser. You are executing document.querySelector
during the prerender (server), before the document is available (browser).
The trick is to use document
only when it is guaranteed to be defined, like in a useLayoutEffect
hook (which is only called after the component is loaded into the DOM):
pages/index.js
import Glide from "./components/Glide"
export default function Home() {
useLayoutEffect(() => {
// glide code here
})
return(
<>
<div className="glide-container">
One way could be to write a hook called useGlide
which executes useLayoutEffect
.
Upvotes: 0