Next.js App Router服务端组件中基于路径高亮Tab的SSR实现
Next.js App Router SSR 下根据路径高亮 Tab 的解决方案
不要再用 referer 判断,直接获取当前请求的路由路径是最可靠的方案,以下是两种适配不同场景的实现方式:
方案一:布局为服务器组件(默认场景)
服务器组件可以直接通过 Next.js 提供的 headers() 函数获取当前路由路径,无需客户端交互,完全在服务端完成判断:
import { headers } from 'next/headers'; export default function RootLayout({ children }: { children: React.ReactNode }) { // 获取当前路由路径,x-nextjs-pathname 是 Next.js 内部维护的请求头,准确可靠 const pathname = headers().get('x-nextjs-pathname') || ''; // 判断当前路径是否属于用户/公司详情页 const isUserTabActive = pathname.startsWith('/user/'); const isCompanyTabActive = pathname.startsWith('/company/'); return ( <html lang="zh-CN"> <body> <nav className="tab-nav"> <a href="/user/details" className={`tab-item ${isUserTabActive ? 'active' : ''}`} > 用户详情 </a> <a href="/company/details" className={`tab-item ${isCompanyTabActive ? 'active' : ''}`} > 公司详情 </a> </nav> <main>{children}</main> </body> </html> ); }
方案优势
x-nextjs-pathname是 Next.js 在服务端处理请求时自动设置的请求头,直接对应当前页面的路由路径,不会像 referer 那样存在为空或不准确的问题。- 整个判断逻辑在服务端完成,渲染出的 HTML 已经带有正确的高亮类,完全符合 SSR 要求。
方案二:布局为客户端组件(含交互场景)
如果你的布局组件需要包含客户端交互逻辑(比如点击 Tab 的动画效果),可以使用 usePathname 钩子,它在 SSR 预渲染阶段也能获取到正确的路径:
'use client'; import { usePathname } from 'next/navigation'; export default function TabNavigation() { const pathname = usePathname(); const isUserTabActive = pathname.startsWith('/user/'); const isCompanyTabActive = pathname.startsWith('/company/'); return ( <nav className="tab-nav"> <a href="/user/details" className={`tab-item ${isUserTabActive ? 'active' : ''}`} > 用户详情 </a> <a href="/company/details" className={`tab-item ${isCompanyTabActive ? 'active' : ''}`} > 公司详情 </a> </nav> ); }
方案说明
usePathname是 Next.js App Router 提供的客户端路由钩子,在 SSR 预渲染时,Next.js 会将当前路径注入到组件中,所以服务端渲染出的 HTML 同样会带有正确的高亮状态,不会出现客户端 hydration 后的状态不一致问题。- 相比 referer,直接基于当前路径判断更准确,不受用户访问方式(直接输入 URL、书签跳转等)的影响。
内容的提问来源于stack exchange,提问作者Sriram Prasanth
相关产品推荐
相关产品推荐

