Vectrum
Sign In
33 lines · 1.1 KB · TypeScript
"use client";

import ReactMarkdown, { defaultUrlTransform } from "react-markdown";
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
import remarkGfm from "remark-gfm";
import { remarkWikiLinks, wikiUrl } from "@/lib/wiki-links";

/**
 * Client-side markdown rendering for editor previews (same pipeline as the server renderer). With
 * `wiki`, links resolve like on a wiki page.
 */
export function MarkdownPreview({ children, wiki }: { children: string; wiki?: string }) {
  return (
    <div className="markdown">
      {children.trim() ? (
        <ReactMarkdown
          remarkPlugins={wiki ? [remarkGfm, [remarkWikiLinks, { base: wiki }]] : [remarkGfm]}
          rehypePlugins={[rehypeRaw, rehypeSanitize]}
          urlTransform={(url, key) => {
            const safe = defaultUrlTransform(url);
            if (!wiki || !safe || /^([a-z][a-z0-9+.-]*:|\/\/|#|\/)/i.test(safe)) return safe;
            return wikiUrl(wiki, safe, key);
          }}
        >
          {children}
        </ReactMarkdown>
      ) : (
        <p className="type-body text-ink3">Nothing to preview</p>
      )}
    </div>
  );
}