39 lines
982 B
TypeScript
39 lines
982 B
TypeScript
"use client";
|
|
|
|
import type { AnchorHTMLAttributes } from "react";
|
|
|
|
type MdLinkProps = AnchorHTMLAttributes<HTMLAnchorElement>;
|
|
|
|
function isExternalHref(href?: string): boolean {
|
|
if (!href) return false;
|
|
if (href.startsWith("/") || href.startsWith("#") || href.startsWith("?")) {
|
|
return false;
|
|
}
|
|
if (href.startsWith("mailto:") || href.startsWith("tel:")) return false;
|
|
try {
|
|
if (typeof window !== "undefined") {
|
|
const url = new URL(href, window.location.origin);
|
|
return url.origin !== window.location.origin;
|
|
}
|
|
} catch {
|
|
/* 相对或非法 URL 当站内 */
|
|
}
|
|
return /^https?:\/\//i.test(href);
|
|
}
|
|
|
|
/** Markdown 链接:外链新开页 */
|
|
export default function MdLink({ href, children, ...rest }: MdLinkProps) {
|
|
const external = isExternalHref(href);
|
|
return (
|
|
<a
|
|
{...rest}
|
|
href={href}
|
|
{...(external
|
|
? { target: "_blank", rel: "noopener noreferrer" }
|
|
: {})}
|
|
>
|
|
{children}
|
|
</a>
|
|
);
|
|
}
|