如何在NextJS App Router中无需放弃SSR实现Locomotive Scroll?
在Next.js App Router中实现Locomotive滚动并保留SSR
完全可以实现,核心是把Locomotive Scroll的初始化逻辑限制在客户端执行,服务端正常渲染页面结构,不会破坏SSR机制。以下是具体实现方案:
实现步骤
安装依赖
先安装Locomotive Scroll包:npm install locomotive-scroll # 或者用yarn yarn add locomotive-scroll创建客户端滚动组件
新建一个带'use client'指令的组件(比如LocomotiveScroll.tsx),把滚动初始化逻辑放在这里:'use client'; import { useEffect, useRef } from 'react'; import LocomotiveScroll from 'locomotive-scroll'; import 'locomotive-scroll/dist/locomotive-scroll.css'; export default function LocomotiveScroll({ children }: { children: React.ReactNode }) { const containerRef = useRef<HTMLDivElement>(null); const scrollRef = useRef<LocomotiveScroll | null>(null); useEffect(() => { if (!containerRef.current) return; // 初始化滚动实例 scrollRef.current = new LocomotiveScroll({ el: containerRef.current, smooth: true, // 其他配置项按需添加 }); // 清理函数:路由切换时销毁实例 return () => { scrollRef.current?.destroy(); }; }, []); return <div ref={containerRef} data-scroll-container>{children}</div>; }在页面中使用
在App Router的页面组件里,直接引入这个客户端组件,把服务端渲染的内容包裹进去:import LocomotiveScroll from '@/components/LocomotiveScroll'; export default function Home() { // 这里的内容会正常SSR渲染 return ( <LocomotiveScroll> <main> <section data-scroll> <h1>SSR渲染的标题</h1> <p>SSR渲染的内容</p> </section> {/* 更多页面内容 */} </main> </LocomotiveScroll> ); }
关键注意事项
- Hydration 匹配:服务端渲染的元素不要在客户端初始化滚动时被修改结构,确保服务端输出的HTML和客户端hydrate后的DOM结构完全一致,避免 hydration 错误。
- 路由切换处理:上面的组件已经在
useEffect的清理函数中销毁了滚动实例,确保路由切换时不会残留旧实例导致异常。 - 样式兼容:确保Locomotive Scroll的CSS正确引入,同时自定义样式时不要破坏滚动容器的布局,避免影响SSR渲染的页面样式。
内容的提问来源于stack exchange,提问作者qvasz
相关产品推荐
相关产品推荐

