import type { AnchorHTMLAttributes } from "react"; import { cn } from "@/lib/utils"; import { isSafeHref, UnsafeLink } from "../messages/markdown-link"; import { CitationLink, extractReactNodeText } from "./citation-link"; function isExternalUrl(href: string | undefined): boolean { return !!href && /^https?:\/\//.test(href); } /** Link renderer for artifact markdown: citation: prefix → CitationLink, otherwise underlined text. */ export function ArtifactLink(props: AnchorHTMLAttributes) { // Reject unsafe schemes so prompt-injected [label](javascript:...) in a .md // artifact preview cannot execute in the main document, matching the guard in // createMarkdownLinkComponent (markdown-link.tsx). if (props.href !== undefined && !isSafeHref(props.href)) { // Intentionally no {...props} spread: anchor-only attributes (href, // target, rel) are not valid on a and would leak the unsafe URL // into the DOM / trigger React DOM warnings. const { className, children } = props; return ( {children} ); } const childrenText = extractReactNodeText(props.children); if (childrenText !== null) { const match = /^citation:(.+)$/.exec(childrenText); if (match) { const [, text] = match; return {text}; } } const { className, target, rel, ...rest } = props; const external = isExternalUrl(props.href); return ( ); }