Next.js14 App Router:服务端渲染菜单的客户端显隐控制方案
无需'use client'实现服务端渲染导航的显示隐藏(兼容爬虫抓取)
下面提供两个完全基于服务端渲染/纯CSS的可行方案,既满足交互需求,又保证谷歌爬虫能抓取完整菜单内容:
方案1:纯CSS :target 伪类控制
利用CSS的:target伪类实现菜单显示切换,完全不需要客户端JavaScript,服务端渲染的完整菜单结构会被爬虫直接抓取。
服务端组件代码
// 服务端组件,无需'use client' import Link from 'next/link'; export default function Page() { return ( <div> {/* 菜单切换按钮,通过锚点指向菜单容器 */} <Link href="#main-nav" className="menu-toggle"> 打开菜单 </Link> {/* 导航菜单容器 */} <nav id="main-nav" className="nav-menu"> {/* 可选:添加关闭按钮,锚点指向页面根元素或空白锚点 */} <Link href="#" className="menu-close"> 关闭菜单 </Link> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </nav> </div> ); }
配套CSS
/* 默认隐藏菜单 */ .nav-menu { display: none; } /* 当锚点指向菜单容器时,显示菜单 */ .nav-menu:target { display: block; } /* 默认隐藏关闭按钮 */ .menu-close { display: none; } /* 菜单打开时显示关闭按钮 */ .nav-menu:target .menu-close { display: inline-block; margin-left: 1rem; }
原理:用户点击按钮时,浏览器URL会跳转到菜单容器的锚点,触发:target伪类,修改菜单的显示状态。爬虫会解析完整的HTML结构,不受CSS显示状态影响。
方案2:URL查询参数控制(服务端渲染时动态调整)
通过URL的查询参数(如?menu=open)让服务端动态决定菜单的显示状态,前端通过修改URL参数实现切换。
服务端组件代码
// 服务端组件,无需'use client' import Link from 'next/link'; import { useSearchParams } from 'next/navigation'; export default function Page() { const searchParams = useSearchParams(); // 读取URL参数判断菜单是否打开 const isMenuOpen = searchParams.get('menu') === 'open'; return ( <div> {/* 根据当前状态生成切换链接 */} <Link href={isMenuOpen ? '/' : '/?menu=open'} className="menu-toggle" > {isMenuOpen ? '关闭菜单' : '打开菜单'} </Link> {/* 服务端动态添加显示类 */} <nav className={`nav-menu ${isMenuOpen ? 'nav-open' : ''}`}> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </nav> </div> ); }
配套CSS
.nav-menu { display: none; } .nav-menu.nav-open { display: block; }
原理:服务端读取URL中的menu参数,渲染时动态给菜单添加/移除显示类。用户点击按钮时跳转到对应参数的URL,服务端重新渲染页面并更新菜单状态。爬虫访问任何版本的URL,都能抓取到完整的菜单HTML。
内容的提问来源于stack exchange,提问作者Leonardo Cortes
相关产品推荐
相关产品推荐

