Skip to main content
Glama
MarkdownPage.tsx2.75 kB
import { useState, useEffect } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import rehypeHighlight from "rehype-highlight"; import rehypeRaw from "rehype-raw"; interface MarkdownPageProps { url: string; title?: string; } function MarkdownPage({ url, title }: MarkdownPageProps) { const [content, setContent] = useState<string>(""); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { setLoading(true); setError(null); // Prepend base URL for GitHub Pages compatibility const baseUrl = import.meta.env.BASE_URL || "/"; const fullUrl = url.startsWith("/") ? `${baseUrl}${url.slice(1)}` : url; fetch(fullUrl) .then((res) => { if (!res.ok) throw new Error(`Failed to load: ${res.status}`); return res.text(); }) .then((text) => { setContent(text); setLoading(false); }) .catch((err) => { setError(err.message); setLoading(false); }); }, [url]); if (loading) { return ( <div className="flex items-center justify-center py-12"> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-500"></div> </div> ); } if (error) { return ( <div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"> <p className="text-red-700 dark:text-red-400">Error loading content: {error}</p> </div> ); } return ( <div> {title && ( <h1 className="text-3xl font-bold text-gray-900 dark:text-white mb-8"> {title} </h1> )} <div className="markdown-body"> <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw, rehypeHighlight]} components={{ img: ({ src, alt }) => { // Handle relative image paths with base URL for GitHub Pages const baseUrl = import.meta.env.BASE_URL || "/"; let imgSrc = src; if (src?.startsWith("./assets/")) { imgSrc = `${baseUrl}assets/${src.replace("./assets/", "")}`; } else if (src?.startsWith("./")) { imgSrc = `${baseUrl}${src.replace("./", "")}`; } return ( <img src={imgSrc} alt={alt || ""} className="max-w-full h-auto my-4 rounded-lg border border-gray-200 dark:border-gray-700" /> ); }, }} > {content} </ReactMarkdown> </div> </div> ); } export default MarkdownPage;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MerzoukeMansouri/adeo-mozaic-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server