Reputation: 301
I've implemented Tiny Slider in my Next.js app which requires an inline script on the page to control the slider's behavior. Now while the script loads properly the first time I launch index.js, however whenever I navigate to another page using Link and come back to index.js, the script doesn't load.
Here's how I've written the script in index.js
{/* Script */}
<Script id='tester'>
{`
var slider = tns({
container: '.my-slider',
items: 6,
autoplay: true,
autoplayTimeout: 2000,
gutter: 20,
autoplayButtonOutput: false,
controls: false,
navPosition: 'bottom',
nav: false,
mouseDrag: true,
arrowKeys: true,
responsive: {
300: {
items: 2,
gutter: 50,
center: true,
fixedWidth: 250,
},
700: {
items: 3,
gutter: 50,
center: true,
fixedWidth: 250,
},
1440: {
items: 3,
gutter: 50,
fixedWidth: 250,
center: true,
}
}
});
`}
</Script>
I need the script to load every time index.js loads, not just the first time around. Any ideas on how I can do this? The entire code is here - https://github.com/YaddyVirus/Esttheva
Upvotes: 6
Views: 1918
Reputation: 581
Here are the steps to adding tiny-slider to a next.js app.
// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.2/tiny-slider.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
import { useEffect, useRef } from "react";
const App = () => {
const ref = useRef(true);
useEffect(() => {
let slider;
// Tiny slider only can be loaded once and can only be loaded clint side
if (typeof window !== "undefined" && ref.current) {
ref.current = false;
// Lazy load the slider code client side
import("tiny-slider").then((x) => {
slider = x.tns({
container: ".slider",
items: 3,
slideBy: "page",
autoplay: true
});
});
}
// Destory the slider when it is unmouted
return slider?.destroy();
}, []);
return (
<div>
<div className="slider">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</div>
);
};
export default App;
Link to code sandbox: https://codesandbox.io/s/tina-slider-nextjs-0z8zi6?file=/pages/index.js:0-806
Here is a couple of key notes about the solution
ref
keeps track of if the hook as already been called (as of react 18 hooks get called twice in dev mode)typeof window !== "undefined"
to ensure that tiny-window only gets loaded client side and not on the server (this causes a "window is undefined" Error)tns
function as per the docsUpvotes: 4