如何让Next.js嵌套Link点击GitHub图标仅新开标签页不跳转项目页
问题
我在开发首页的项目展示组件,想要实现两个效果:
- 点击组件整体区域(除GitHub图标外)时,跳转到对应项目详情页
- 点击组件内的GitHub图标时,仅在新标签页打开GitHub链接,原页面不跳转至项目页
当前代码中,GitHub的链接嵌套在项目页的<Link>里,导致点击GitHub图标时,不仅会在新标签打开GitHub,原页面还会触发项目页的跳转,即使设置了target="_blank"也无法阻止父级的跳转行为。
解决办法
核心是阻止GitHub图标的点击事件向上冒泡到父级的项目<Link>,同时用原生<a>标签处理外部链接更适配需求,具体修改如下:
修改后的完整代码
"use client"; import Image from "next/image"; import Link from "next/link"; type ProjectType = { img: string; title: string; slug: string; desc: string; overview: string; role: string; impact: string; tags: Array<string>; startDate: Date; endDate: Date; github?: string; paper?: string; link?: string; area: string; }; function Tag({ tag }: { tag: string }) { return ( <div className=" duration-500 ease-in-out text-center text-sm rounded-full p-2 mr-4 mb-4 w-1/5 text-primary-white bg-primary-white bg-opacity-50 group-hover:bg-primary-color group-hover:bg-opacity-100 "> {tag} </div> ); } export default function ProjectFeatured({ project, idx, }: { project: ProjectType; idx: number; }) { const options = { month: "short" as const, year: "numeric" as const }; const isEven = idx % 2 == 0; const classNameString = "group w-full h-full p-12 rounded-3xl text-primary-white flex flex-col space-y-8 sm:space-y-0 sm:space-x-8 duration-500 ease-in-out hover:bg-primary-hover " + (isEven ? "sm:flex-row" : "sm:flex-row-reverse sm:space-x-reverse"); return ( <Link href={"/projects/" + project.slug}> <div className={classNameString}> {/* Image */} <div className="flex w-1/2 items-center justify-center"> <Image className="object-cover h-full rounded-xl" src={project.img} alt="Project Image" width={1000} height={1000} draggable={false} /> </div> {/* Text */} <div className="flex flex-col w-3/4 justify-between space-y-12"> {/* Title and desc */} <div className="flex flex-col space-y-4"> {/* Title */} <div> <div className="text-xxl">{project.title}</div> </div> {/* Desc */} <div>{project.desc}</div> </div> {/* Tags and links */} <div className="flex flex-col space-y-4"> {/* Tags */} <div className="flex flex-row flex-wrap"> {project.tags.map((tag, idx) => ( <Tag tag={tag} key={idx} /> ))} </div> {/* Links */} <div className="flex flex-row space-x-2 "> {project.github ? ( <a className="w-full" href={project.github} target="_blank" rel="noopener noreferrer" onClick={(e) => e.stopPropagation()} > <Image className=" hover:animate-shrinkWiggle" src={"svgs/github.svg"} alt="Github Icon" width={20} height={20} /> </a> ) : ( <div /> )} </div> </div> </div> </div> </Link> ); }
关键修改说明
- 替换Next.js Link为原生a标签:对于外部链接,原生
<a>标签更适配新标签页打开的需求,同时添加rel="noopener noreferrer"符合安全规范 - 添加事件阻止冒泡:
onClick={(e) => e.stopPropagation()}会阻止点击事件向上传递到父级的项目<Link>,彻底避免点击GitHub图标时触发项目页跳转 - 保留target="_blank":确保GitHub链接始终在新标签页打开
内容的提问来源于stack exchange,提问作者John Xie
相关产品推荐
相关产品推荐

