# react-md-editor **Repository Path**: uiw/react-md-editor ## Basic Information - **Project Name**: react-md-editor - **Description**: 轻量级具有预览功能的 Markdown 编辑器,基于Textarea 封装,不依赖第三方编辑器,使用 React.js 和 TypeScript 实现。 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: https://uiw.gitee.io/react-md-editor/ - **GVP Project**: No ## Statistics - **Stars**: 69 - **Forks**: 14 - **Created**: 2019-08-25 - **Last Updated**: 2025-06-13 ## Categories & Tags **Categories**: text-editor, react-extensions **Tags**: None ## README

react-md-editor logo

Downloads jsDelivr CDN npm bundle size Coverage Status
Build & Deploy Open in unpkg Gitee npm version

A simple markdown editor with preview, implemented with React.js and TypeScript. This React Component aims to provide a simple Markdown editor with syntax highlighting support. This is based on `textarea` encapsulation, so it does not depend on any modern code editors such as Acs, CodeMirror, Monaco etc. ### Features - 📑 Indent line or selected text by pressing tab key, with customizable indentation. - ♻️ Based on `textarea` encapsulation, does not depend on any modern code editors. - 🚧 Does not depend on the [`uiw`](https://github.com/uiwjs/uiw) component library. - 🚘 Automatic list on new lines. - 😻 GitHub flavored markdown support. - 🌒 Support dark-mode/night-mode **@v3.11.0+**. - 💡 Support [next.js](https://github.com/uiwjs/react-md-editor/issues/52#issuecomment-848969341), [Use examples](#support-nextjs) in [next.js](https://nextjs.org/). ### Quick Start ```bash npm i @uiw/react-md-editor ``` ### Using [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/markdown-editor-for-react-izdd6?fontsize=14&hidenavigation=1&theme=dark) [![Open in Github gh-pages](https://img.shields.io/badge/Open%20In-Github%20gh--pages-blue?logo=github)](https://uiwjs.github.io/react-md-editor/) [![Open in Gitee gh-pages](https://img.shields.io/badge/Open%20In-Gitee%20gh--pages-blue?logo=web)](https://uiw.gitee.io/react-md-editor/) ```jsx mdx:preview import React from "react"; import MDEditor from '@uiw/react-md-editor'; export default function App() { const [value, setValue] = React.useState("**Hello world!!!**"); return (
); } ``` ### Special Markdown syntax **Supports for CSS Style** Use HTML comments `` to let Markdown support style customization. ```markdown ## Title Markdown Supports **Style** ``` **Ignore content display via HTML comments** Shown in GitHub readme, excluded in HTML. ```markdown # Hello World Hello World Good! ``` Output: ```html

Hello World

Good!

``` ### Security Please note markdown needs to be sanitized if you do not **completely trust** your authors. Otherwise, your app is vulnerable to XSS. This can be achieved by adding [rehype-sanitize](https://github.com/rehypejs/rehype-sanitize) as a plugin. ```jsx mdx:preview import React from "react"; import MDEditor from '@uiw/react-md-editor'; import rehypeSanitize from "rehype-sanitize"; export default function App() { const [value, setValue] = React.useState(`**Hello world!!!** `); return (
); } ``` ### Custom Toolbars [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/react-md-editor-custom-toolbars-m2n10?fontsize=14&hidenavigation=1&theme=dark) ```jsx mdx:preview import React from "react"; import MDEditor, { commands } from '@uiw/react-md-editor'; const title3 = { name: 'title3', keyCommand: 'title3', buttonProps: { 'aria-label': 'Insert title3' }, icon: ( ), execute: (state, api) => { let modifyText = `### ${state.selectedText}\n`; if (!state.selectedText) { modifyText = `### `; } api.replaceSelection(modifyText); }, }; const title2 = { name: 'title2', keyCommand: 'title2', render: (command, disabled, executeCommand) => { return ( ) }, execute: (state, api) => { let modifyText = `## ${state.selectedText}\n`; if (!state.selectedText) { modifyText = `## `; } api.replaceSelection(modifyText); }, } export default function App() { const [value, setValue] = React.useState("Hello Markdown! `Tab` key uses default behavior"); return (
), children: ({ close, execute, getState, textApi }) => { return (
My Custom Toolbar
); }, execute: (state, api) => { console.log('>>>>>>update>>>>>', state) }, buttonProps: { 'aria-label': 'Insert title'} }), ]} />
); } ``` Customize the toolbar with `commands` and `extraCommands` props. ```jsx mdx:preview import React from "react"; import MDEditor, { commands } from '@uiw/react-md-editor'; export default function App() { const [value, setValue] = React.useState("Hello Markdown! `Tab` key uses default behavior"); return (
), children: ({ close, execute, getState, textApi }) => { return (
My Custom Toolbar
); }, execute: (state, api) => { console.log('>>>>>>update>>>>>', state) }, buttonProps: { 'aria-label': 'Insert title'} }), commands.divider, commands.fullscreen ]} />
); } ``` re-render `toolbar` element. ```jsx mdx:preview import React from "react"; import MDEditor, { commands } from '@uiw/react-md-editor'; export default function App() { const [value, setValue] = React.useState("Hello Markdown! `Tab` key uses default behavior"); return (
{ if (command.keyCommand === 'code') { return ( ) } } }} />
); } ``` Custom Preview Command Tool [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/react-md-editor-custom-toolbars-https-github-com-uiwjs-react-md-editor-issues-433-9mwuob?fontsize=14&hidenavigation=1&theme=dark) ```jsx mdx:preview import React, { useContext } from "react"; import MDEditor, { commands, EditorContext } from "@uiw/react-md-editor"; const Button = () => { const { preview, dispatch } = useContext(EditorContext); const click = () => { dispatch({ preview: preview === "edit" ? "preview" : "edit" }); }; if (preview === "edit") { return ( ); } return ( ); }; const codePreview = { name: "preview", keyCommand: "preview", value: "preview", icon: