uiwjs / uiwjs/react-md-editor

getting rehypePrism and rehypeSanitize plugins to work at the same time

Open
#585 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.9k
Forks
201
Avg merge
12m
Merged PRs (30d)
1

Description

I have separate components. One for creating new markdown and another for viewing saved markdowns on a separate page.

This is in a nextjs app but I don't think it's a next problem.

If I use rehypePrism it works. If I use rehypeSanitize it works. But if I use them both, then the prism classes don't get added to the output.

I worked around it in my viewer component by sanitizing the data before feeding it to the viewer but would rather not have to work around it like this and don't know how to do the same with the editor

MarkDownEditor.tsx

'use client';
import MDEditor from '@uiw/react-md-editor';
import rehypeSanitize from 'rehype-sanitize';
import rehypePrism from 'rehype-prism-plus';
import { forwardRef } from 'react';

export type MarkDownEditorProps = {
  name: string;
  value: string;
  onChange: (...event: any[]) => void;
  onBlur: () => void;
};

const MarkDownEditor = forwardRef<HTMLTextAreaElement, MarkDownEditorProps>(
  ({ name, value, onChange, onBlur }, ref) => {
    MarkDownEditor.displayName = 'MarkDownEditor';
    return (
      <div className="container">
        <MDEditor
          ref={ref}
          onBlur={onBlur}
          value={value}
          onChange={onChange}
          textareaProps={{
            id: name,
            name: name,
            placeholder: 'Yo, you got issues?',
          }}
          preview="edit"
          previewOptions={{
            rehypePlugins: [[rehypeSanitize]],
          }}
          components={{
            toolbar: (command, disabled, executeCommand) => {
              if (command.keyCommand === 'code') {
                return (
                  <button
                    aria-label="Insert code"
                    disabled={disabled}
                    onClick={event => {
                      event.stopPropagation();
                      executeCommand(command, command.groupName);
                    }}
                  >
                    Code
                  </button>
                );
              }
            },
          }}
        />
      </div>
    );
  },
);

export default MarkDownEditor;

MarkDownViewer.tsx

'use client';
import { useEffect, useState } from 'react';
import MDEditor from '@uiw/react-md-editor';
import rehypePrism from 'rehype-prism-plus';
import rehypeSanitize from 'rehype-sanitize';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
import { unified } from 'unified';

export type MarkDownViewerProps = {
  source: string;
};

const MarkDownViewer = ({ source }: MarkDownViewerProps) => {
  const [cleanSource, setCleanSource] = useState('foo');
  useEffect(() => {
    const getCleanSource = async () => {
      const data = await unified()
        .use(rehypeParse, { fragment: true })
        .use(rehypeSanitize)
        .use(rehypeStringify)
        .process(source);

      setCleanSource(String(data));
    };

    getCleanSource().catch(console.error);
  }, [source]);
  return (
    <div className="p-1 px-4">
      <MDEditor.Markdown
        source={cleanSource}
        rehypePlugins={[[rehypePrism, { ignoreMissing: true }]]}
      />
    </div>
  );
};

export default MarkDownViewer;

Is there an option to tell the editor which order to run the plugins in so it can run through sanitize and then through prism? Any ideas why prism isn't processing if I try to use both plugins?

Thanks

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with MarkDownEditor.tsx and inspect how previewOptions passes rehypeSanitize and rehypePrism to the preview pipeline. Compare that configuration with the unified pipeline in MarkDownViewer.tsx, including its plugin order. Done means the editor preview sanitizes content while retaining the Prism classes and highlighting.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.