diff --git a/packages/ui/app/src/components/FernLink.tsx b/packages/ui/app/src/components/FernLink.tsx index b3eb507098..341da535c0 100644 --- a/packages/ui/app/src/components/FernLink.tsx +++ b/packages/ui/app/src/components/FernLink.tsx @@ -1,14 +1,15 @@ import { ExternalLinkIcon } from "@radix-ui/react-icons"; import Link from "next/link"; -import { ReactElement, type ComponentProps } from "react"; +import { ReactElement, useEffect, useState, type ComponentProps } from "react"; import { format, parse, resolve, type UrlObject } from "url"; +import { useDocsContext } from "../contexts/docs-context/useDocsContext"; import { useNavigationContext } from "../contexts/navigation-context"; interface FernLinkProps extends ComponentProps { showExternalLinkIcon?: boolean; } -export function FernLink({ showExternalLinkIcon, ...props }: FernLinkProps): ReactElement { +export function FernLink({ showExternalLinkIcon = false, ...props }: FernLinkProps): ReactElement { const url = toUrlObject(props.href); const isExternalUrl = checkIsExternalUrl(url); @@ -19,12 +20,11 @@ export function FernLink({ showExternalLinkIcon, ...props }: FernLinkProps): Rea return ; } - return ( - - {props.children} - {isExternalUrl && showExternalLinkIcon && } - - ); + if (isExternalUrl) { + return ; + } + + return ; } function FernRelativeLink(props: ComponentProps) { @@ -33,6 +33,45 @@ function FernRelativeLink(props: ComponentProps) { return ; } +interface FernExternalLinkProps extends Omit, "href"> { + showExternalLinkIcon: boolean; + url: UrlObject; +} + +function FernExternalLink({ showExternalLinkIcon, url, ...props }: FernExternalLinkProps) { + const { domain } = useDocsContext(); + const [host, setHost] = useState(domain); + useEffect(() => { + if (typeof window !== "undefined") { + setHost(window.location.host); + } + }, []); + + // if the link is to a different domain, always open in a new tab + // TODO: if the link is to the same domain, we should check if the page is a fern page, and if so, use the Link component to leverage client-side navigation + const isSameSite = host === url.host; + return ( + // eslint-disable-next-line react/jsx-no-target-blank + + {props.children} + {!isSameSite && showExternalLinkIcon && } + + ); +} + export function toUrlObject(url: string | UrlObject): UrlObject { if (url == null) { return {}; @@ -61,10 +100,6 @@ export function checkIsExternalUrl(url: UrlObject): boolean { } export function checkIsRelativeUrl(url: UrlObject): boolean { - if (checkIsExternalUrl(url)) { - return false; - } - if (url.href == null) { return true; }