Closed PixelPage-YT closed 6 months ago
you should instanciate Lenis inside a useEffect, otherwise it's gonna fail on SSR
'use client'; import Lenis from '@studio-freight/lenis'; const SmoothScroller = () => { useEffect(()=>{ const lenis = new Lenis(); function raf(time: any) { lenis.raf(time); requestAnimationFrame(raf); } raf() return () => { lenis.destroy() } }, []) }; export default SmoothScroller;
surprisingly its just work , thanks for this answer
@yuxxeun I wouldn't recommend this solution, it has an issue where scroll doesn't reset on route change and performance-wise tempus
does a better job
these are better ways to manage it if you are using app dir
if you want to use lenis instance in your components:
"use client";
import Lenis from "@studio-freight/lenis";
import Tempus from "@studio-freight/tempus";
import router from "next/router";
import { createContext, useContext, useLayoutEffect, useState } from "react";
export const lenisCTX = createContext<Lenis | null>(null);
export const useLenis = () => useContext(lenisCTX);
export default function Lenify({ children }: { children: React.ReactNode }) {
const [lenis, setLenis] = useState<Lenis | null>(null);
useLayoutEffect(() => {
const lenis = new Lenis();
setLenis(lenis);
const resize = setInterval(() => {
lenis.resize();
}, 150);
function onFrame(time: number) {
lenis.raf(time);
}
const unsubscribe = Tempus.add(onFrame);
router.events.on("routeChangeStart", () => {
lenis.scrollTo(0, { immediate: true });
});
return () => {
unsubscribe();
clearInterval(resize);
setLenis(null);
lenis.destroy();
};
}, []);
return <lenisCTX.Provider value={lenis}>{children}</lenisCTX.Provider>;
}
and If you just want to initiate lenis
"use client";
import Tempus from "@studio-freight/tempus";
import Lenis from "@studio-freight/lenis";
import { useEffect, useLayoutEffect, useRef } from "react";
import { usePathname, useSearchParams } from "next/navigation";
export default function Lenify() {
const lenis = useRef<Lenis | null>(null);
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (lenis.current) lenis.current!.scrollTo(0, { immediate: true });
}, [pathname, searchParams, lenis]);
useLayoutEffect(() => {
lenis.current = new Lenis();
const resize = setInterval(() => {
lenis.current!.resize();
}, 150);
function onFrame(time: number) {
lenis.current!.raf(time);
}
const unsubscribe = Tempus.add(onFrame);
return () => {
unsubscribe();
clearInterval(resize);
lenis.current!.destroy();
lenis.current = null;
};
}, []);
return null;
}
@yuxxeun I wouldn't recommend this solution, it has an issue where scroll doesn't reset on route change and performance-wise
tempus
does a better jobthese are better ways to manage it if you are using app dir
if you want to use lenis instance in your components:
"use client"; import Lenis from "@studio-freight/lenis"; import Tempus from "@studio-freight/tempus"; import router from "next/router"; import { createContext, useContext, useLayoutEffect, useState } from "react"; export const lenisCTX = createContext<Lenis | null>(null); export const useLenis = () => useContext(lenisCTX); export default function Lenify({ children }: { children: React.ReactNode }) { const [lenis, setLenis] = useState<Lenis | null>(null); useLayoutEffect(() => { const lenis = new Lenis(); setLenis(lenis); const resize = setInterval(() => { lenis.resize(); }, 150); function onFrame(time: number) { lenis.raf(time); } const unsubscribe = Tempus.add(onFrame); router.events.on("routeChangeStart", () => { lenis.scrollTo(0, { immediate: true }); }); return () => { unsubscribe(); clearInterval(resize); setLenis(null); lenis.destroy(); }; }, []); return <lenisCTX.Provider value={lenis}>{children}</lenisCTX.Provider>; }
and If you just want to initiate lenis
"use client"; import Tempus from "@studio-freight/tempus"; import Lenis from "@studio-freight/lenis"; import { useEffect, useLayoutEffect, useRef } from "react"; import { usePathname, useSearchParams } from "next/navigation"; export default function Lenify() { const lenis = useRef<Lenis | null>(null); const pathname = usePathname(); const searchParams = useSearchParams(); useEffect(() => { if (lenis.current) lenis.current!.scrollTo(0, { immediate: true }); }, [pathname, searchParams, lenis]); useLayoutEffect(() => { lenis.current = new Lenis(); const resize = setInterval(() => { lenis.current!.resize(); }, 150); function onFrame(time: number) { lenis.current!.raf(time); } const unsubscribe = Tempus.add(onFrame); return () => { unsubscribe(); clearInterval(resize); lenis.current!.destroy(); lenis.current = null; }; }, []); return null; }
ah okey i'll try it soon, tbh, i don't realize this package have an issue (scroll doesn't reset on route change). thanks for giving me better way to use Lenis package with Next.js (app dir).
Our starter Satus is now Next.js App based, it should solve most of issues you had. I'm closing this issue and let you open new ones if you need to.
Describe the bug
Current Workaround If you have resizing issues, consider this variant: https://github.com/studio-freight/lenis/issues/170#issuecomment-1635443119
Normal variant below:
I'm going to leave this open until it's fixed. https://github.com/developit/microbundle/issues/1049 Also needs to be fixed if we don't want to write 'use client'; on the beginning of the lenis wrapper.