Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@aegisjsproject/md-editor

AegisJSProject44MIT1.0.0

A custom Markdown editor component with preview as a form input element

aegis, aegisjsproject, markdown, custom-input, secure, sanitizer-api, custom-elements, web-components, md-editor, markdown-editor, markdown-viewer, form-associated-custom-element, form-associated

readme

@aegisjsproject/md-editor

A custom Markdown editor component with preview as a form input element

CodeQL Node CI Lint Code Base

GitHub license GitHub last commit GitHub release GitHub Sponsors

npm node-current npm bundle size gzipped npm

GitHub followers GitHub forks GitHub stars Twitter Follow

Donate using Liberapay


Node Instructions

npm i @aegisjsproject/md-editor

Using <script type="importmap"> and a CDN

<script type="importmap">
  {
    "imports": {
      "@aegisjsproject/md-editor": "https://unpkg.com/@aegisjsproject/md-editor@1.0.0/md-editor.min.js"
    }
  }
</script>

Just Using a <script>

<script src="https://unpkg.com/@aegisjsproject/md-editor@1.0.0/md-editor.min.js" crossorigin="anonymous" referrerpolicy="no-referrer" defer=""></script>

Example Usage

Just using HTML

<form id="post">
  <label for="content">Content</label>
  <!-- This behaves basically like a textarea or any input -->
  <md-editor name="content" id="content" minlength="40" mode="editor" required="">
    # Hello, World!
    ![foo](/img/foo.png)
  </md-editor>
  <!-- Rest of form stuff -->
</form>

Creating through Scripting

// Need to import if not already added
import '@aegisjsproject/md-editor';

// Get the component class
const HTMLMarkdownEditorElement = customElements.get('md-editor');

// Create and setup the element
const editor = new HTMLMarkdownEditorElement();
editor.name = 'content';
editor.id = 'content';

// Optionally bind to `history.state[whatever]
editor.textContent = history.state?.content;
editor.addEventListener('change', ({ target }) => history.replaceState({ content: target.value }, '', location.href), { passive: true });

// Add to the form, after its `<label>`
document.querySelector(`label[for="${editor.id}"]`).after(editor);

Usage Notes and Browser APIs

This component utilizes some proposed and experimental APIs including Element.prototype.setHTML (this Sanitizer API) and String.dedent. These APIs MUST be polyfilled. You may find the required polyfills in @shgysk8zer0/polyfills or provide your own.

Security

Like all @aegisjsproject libraries, this component is indended to be safe and compatible in highly secure contexts. It is designed to work with a very restricted CSP as well as the Trusted Types API.

Example CSP

Note the SRI Integrity used for a <script type="importmap"> and the Trusted Types Policy of aegis-sanitizer#html (required for the Sanitizer API polyfill).

Content-Security-Policy: default-src 'self'; script-src 'self' https://unpkg.com/@shgysk8zer0/ https://unpkg.com/@aegisjsproject/ 'sha384-XYouuKGvd2BSrapxPZFWENl9b0loR7EVyC2cls6tQ/Oa+3R/uWw6TQ+nWa4/zt9l'; style-src 'self' https://unpkg.com/@highlightjs/ https://unpkg.com/@aegisjsproject/; img-src 'self'; trusted-types aegis-sanitizer#html; require-trusted-types-for 'script';

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[v1.0.0] - 2025-04-30

Initial Release