Next.js 13中强制<Link>组件跳转后滚动至布局顶部
解决Next.js App Router动态路由跳转后不滚动到顶部的问题
针对共享父布局的动态路由场景,点击同路由下的<Link>后页面保留滚动位置的问题,给你几个不用把整个父布局转成客户端组件的实用方案:
方案1:直接给<Link>添加scroll属性
Next.js的<Link>组件默认在同路由(比如[slug]下的不同文章)跳转时会保留滚动位置,但可以通过显式设置scroll={true}强制跳转后滚动到顶部,这是最直接的方法:
import Link from 'next/link'; // 文章组件里的动态Link示例 <Link href={`/${targetSlug}`} scroll={true}> 查看另一篇文章 </Link>
方案2:封装全局自定义Link组件
如果页面里有大量动态生成的<Link>,不想逐个手动添加scroll属性,可以封装一个默认开启滚动到顶部的自定义Link组件,全局复用:
// components/CustomLink.tsx import Link from 'next/link'; import type { LinkProps } from 'next/link'; const CustomLink = ({ children, ...props }: LinkProps) => { // 默认强制滚动到顶部,也可通过传入props.scroll覆盖行为 return <Link {...props} scroll={props.scroll ?? true}>{children}</Link>; }; export default CustomLink;
之后页面里统一使用这个自定义组件:
import CustomLink from '@/components/CustomLink'; <CustomLink href={`/${targetSlug}`}> 查看另一篇文章 </CustomLink>
方案3:添加轻量客户端组件处理全局滚动
如果想彻底统一处理所有同路由跳转的滚动行为,又不想把父布局转成客户端组件,可以单独创建一个仅负责滚动的小型客户端组件,嵌入到父布局中:
// components/ScrollToTop.tsx 'use client'; import { usePathname } from 'next/navigation'; import { useEffect } from 'react'; export default function ScrollToTop() { const pathname = usePathname(); useEffect(() => { // 路由变化时滚动到顶部,behavior可选'smooth'或'auto' window.scrollTo({ top: 0, behavior: 'smooth' }); }, [pathname]); return null; // 该组件无需渲染可视内容 }
然后在父layout.tsx中引入这个组件(布局依然保持服务器组件特性):
// layout.tsx import ScrollToTop from '@/components/ScrollToTop'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <ScrollToTop /> {children} </body> </html> ); }
这个方案仅引入了一个极小的客户端组件,不会影响布局的服务器渲染能力,能完美解决全局滚动需求。
内容的提问来源于stack exchange,提问作者Callum Kloos
相关产品推荐
相关产品推荐

