React Logoreact-markdown

`react-markdown` is a popular React component that allows you to effortlessly render Markdown content as HTML within your React applications. It acts as a wrapper around the `remark` and `rehype` ecosystems, providing a secure, highly customizable, and extensible way to display Markdown.

Why use `react-markdown`?
* Ease of Integration: It's a simple React component that takes Markdown as a string prop and renders it directly.
* Security: By default, it sanitizes the input to prevent XSS (Cross-Site Scripting) vulnerabilities, making it safe to render user-generated content.
* Customizability: You have fine-grained control over how different Markdown elements are rendered. You can replace default HTML elements (like `<h1>`, `<p>`, `<a>`) with your own custom React components, allowing for seamless styling and interactive elements.
* Extensibility: It leverages the `remark` plugin ecosystem, allowing you to extend its functionality with various plugins for features like GitHub Flavored Markdown (GFM), syntax highlighting, math rendering, and more.
* Performance: It's optimized for performance, especially when dealing with large Markdown inputs.

Key Features:
* CommonMark Compliance: Parses Markdown according to the CommonMark specification by default.
* Plugin Support: Easily integrate `remark` and `rehype` plugins to add features like GFM (`remark-gfm`), raw HTML rendering (`rehype-raw`), or custom syntax (`remark-prism`).
* Custom Renderers: Override default HTML element rendering using the `components` prop. This is powerful for styling or adding interactivity, allowing you to map HTML tags (e.g., `h1`, `p`, `a`) to your own React components.
* Security by Default: Sanitizes potentially dangerous HTML and attributes to prevent malicious scripts from running, offering a safe-by-default approach.

Installation:
You typically install it via npm or yarn:
`npm install react-markdown remark-gfm` (including `remark-gfm` as it's a commonly used plugin for extended Markdown syntax)

Basic Usage:
You simply pass your Markdown string as the `children` prop to the `ReactMarkdown` component.

Advanced Usage (Custom Components & Plugins):
You can pass an object to the `components` prop, where keys are HTML tag names (e.g., `h1`, `p`, `a`) and values are the React components you want to use for rendering those tags. You can also pass an array of `remarkPlugins` to extend its parsing capabilities with additional Markdown features.

Example Code

import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm'; // For GitHub Flavored Markdown

// Custom component for rendering h1 tags
const CustomH1 = ({ children }) => (
  <h1 style={{ color: 'navy', borderBottom: '2px solid navy', paddingBottom: '5px' }}>
    {children}
  </h1>
);

// Custom component for rendering anchor links
const CustomLink = ({ href, children }) => (
  <a href={href} target="_blank" rel="noopener noreferrer" style={{ color: 'green', fontWeight: 'bold' }}>
    {children}
  </a>
);

function MarkdownRenderer() {
  const [markdownInput, setMarkdownInput] = useState(
    `# Welcome to React Markdown!
    
This is a paragraph with bold text and *italic* text.

You can also create [links](https://reactjs.org) and add images:
![React Logo](https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg)

 Features:
-   List items are easy.
-   Code blocks too:
    ```javascript
    const greeting = "Hello, World!";
    console.log(greeting);
    ```

---

 GitHub Flavored Markdown (GFM) Example:
-   [x] Task list item 1
-   [ ] Task list item 2

| Header 1 | Header 2 |
| -------- | -------- |
| Cell 1   | Cell 2   |
`
  );

  return (
    <div style={{ fontFamily: 'Arial, sans-serif', maxWidth: '800px', margin: '20px auto', padding: '20px', border: '1px solid #ddd', borderRadius: '8px' }}>
      <h1>React Markdown Example</h1>
      <textarea
        style={{ width: '100%', minHeight: '200px', marginBottom: '20px', padding: '10px', fontSize: '16px', border: '1px solid #ccc', borderRadius: '4px' }}
        value={markdownInput}
        onChange={(e) => setMarkdownInput(e.target.value)}
        placeholder="Enter your Markdown here..."
      />
      <hr />
      <h2>Rendered Output:</h2>
      <div style={{ border: '1px solid #eee', padding: '15px', borderRadius: '4px', backgroundColor: '#f9f9f9' }}>
        <ReactMarkdown
          remarkPlugins={[remarkGfm]} // Enable GitHub Flavored Markdown features like task lists and tables
          components={{
            h1: CustomH1, // Use our custom H1 component for all H1 tags
            a: CustomLink, // Use our custom Link component for all anchor tags
            // You can customize any HTML tag, e.g., 'p', 'li', 'img', 'code', etc.
            // p: ({node, ...props}) => <p style={{lineHeight: '1.6'}} {...props} />,
            // code: ({node, inline, className, children, ...props}) => {
            //   const match = /language-(\w+)/.exec(className || '');
            //   return !inline && match ? (
            //     <SyntaxHighlighter
            //       style={dracula}
            //       language={match[1]}
            //       PreTag="div"
            //       {...props}
            //     >
            //       {String(children).replace(/\n$/, '')}
            //     </SyntaxHighlighter>
            //   ) : (
            //     <code className={className} {...props}>
            //       {children}
            //     </code>
            //   );
            // }
          }}
        >
          {markdownInput}
        </ReactMarkdown>
      </div>
    </div>
  );
}

export default MarkdownRenderer;