"use client" import NextLink from "next/link" import { usePathname, useRouter, useSearchParams } from "next/navigation" import { startTransition, useCallback, useMemo } from "react" import useRouterTransitionStore from "@/stores/router-transition" import { useCheckIfExternalLink } from "@/hooks/useCheckIfExternalLink" import { trackClick, trackPageViewStart } from "@/utils/tracking" import { linkVariants } from "./variants" import type { LinkProps } from "./link" export default function Link({ active, className, color, href, partialMatch = false, textDecoration, size, scroll = true, prefetch, variant, weight, trackingId, onClick, /** * Decides if the link should include the current search params in the URL */ keepSearchParams, ...props }: LinkProps) { const currentPageSlug = usePathname() const searchParams = useSearchParams() let isActive = active || currentPageSlug === href if (partialMatch && !isActive) { isActive = currentPageSlug === href } const classNames = linkVariants({ active: isActive, className, textDecoration, color, size, weight, variant, }) const router = useRouter() const fullUrl = useMemo(() => { if (!keepSearchParams || !searchParams.size) return href const delimiter = href.includes("?") ? "&" : "?" return `${href}${delimiter}${searchParams}` }, [href, searchParams, keepSearchParams]) // TODO: Remove this check (and hook) and only return when current web is deleted const isExternal = useCheckIfExternalLink(href) const startRouterTransition = useRouterTransitionStore( (state) => state.startRouterTransition ) const trackClickById = useCallback(() => { if (trackingId) { trackClick(trackingId) } }, [trackingId]) const linkProps = { href: fullUrl, className: classNames, } return isExternal ? ( { if (onClick) { onClick(e) } }} /> ) : ( { if (onClick) { onClick(e) } if (trackingId) { trackClickById() } if (props.target === "_blank") { // If link should open in new tab, we don't want to // track navigation nor start a router transition. return } if (href.startsWith("tel:") || href.startsWith("mailto:")) { // If href contains tel or mailto protocols we don't want to // track navigation nor start a router transition. return } e.preventDefault() trackPageViewStart() startTransition(() => { startRouterTransition() router.push(fullUrl, { scroll }) }) }} id={trackingId} {...props} {...linkProps} /> ) }