javascripttypescriptnext.jshyperlinktailwind-css

How to make a Next.JS Link inside a Link only open a new tab with internal url and not redirect to external url?


I am creating a project component for my homepage which displays a project. When the user clicks on the component, I want the overall component to redirect to the specific project page. However, when they specifically click the GitHub icon, I want the website to open the GitHub link in a new tab and not redirect to the specific project page. Here is my current code for the component.

"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>
              {/* <Image/> */}
            </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 ? (
                <Link className="w-full" href={project.github} target="_blank">
                  <Image
                    className=" hover:animate-shrinkWiggle"
                    src={"svgs/github.svg"}
                    alt="Github Icon"
                    width={20}
                    height={20}
                  />
                </Link>
              ) : (
                <div />
              )}
            </div>
          </div>
        </div>
      </div>
    </Link>
  );
}

I tried removing the target="_blank" which does make clicking the GitHub icon redirect to the GitHub page, but I want the GitHub page to open in a new tab and not redirect the original tab to the project page.


Solution

  • I think you can try adding a onClick handler to the inner Link component (i.e. the Github link), and see if it helps

    <Link className="w-full" href={project.github} target="_blank" 
      onClick={(event) => event.stopPropagation()} // <--- Add this
    >
     // ...
    </Link>
    

    Further reading: