Skip to main content

Symbolleiste, Live-Vorschau und WYSIWYG im Textbereich, den Sie bereits haben

Zuletzt aktualisiert:

Ein Markdown-Editor, der Ihren Textbereich erweitert, anstatt ihn zu ersetzen, sodass Formularübermittlung, Validierung und Pflichtfelder weiterhin funktionieren. WYSIWYG- und einfacher Markdown-Modus, Live-Vorschau, Suchen & Ersetzen, RTL-Unterstützung, Dunkelmodus. Funktioniert eigenständig mit Django, Laravel, Rails, Node.js, PHP und jedem Stack.

Kein Frutjam und kein Tailwind erforderlich. Die Stile sind gebündelt, sodass der Editor in jedes Projekt eingefügt werden kann.

Installation

NPM (Bundler: Vite, Webpack, Rollup usw.)

bash
npm install markdown-text-editor
javascript
1
2
import MarkdownEditor from 'markdown-text-editor';
new MarkdownEditor('#markdown-editor');

TypeScript-Definitionen werden mit dem Paket geliefert, sodass Optionen, Symbolleisteneinträge und Variablenformen ohne zusätzliche Installation überprüft und automatisch vervollständigt werden.

CDN: ES-Modul

html
1
2
3
4
<script type="module">
  import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/+esm';
  new MarkdownEditor('#markdown-editor');
</script>

CDN: globales Skript-Tag (IIFE)

Kein Import erforderlich: MarkdownEditor ist automatisch als globale Variable verfügbar.

html
1
2
3
4
5
6
7
8
9
<form action="/api/save" method="POST">
  <textarea id="markdown-editor" name="content"># Hello World</textarea>
  <button type="submit">Save Content</button>
</form>

<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>
  new MarkdownEditor('#markdown-editor');
</script>

Demo zum Markdown-Editor

Schnellstart

Übergeben Sie ein Optionsobjekt, um den Editor anzupassen. Alle Optionen sind optional: Lassen Sie alle weg, um den Standardwert zu verwenden.

javascript
1
2
3
4
const editor = new MarkdownEditor('#markdown-editor', {
  placeholder: 'Write your markdown...',
  toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'],
});

Die Philosophie: „Native-First“

Die meisten Redakteure unterbrechen den Standard-Web-Workflow. MarkdownEditor begrüßt es. Weil es direkt auf einem sitzt <textarea>, müssen Sie keinen neuen Umgang mit Daten erlernen.

  • Keine Datenbindung erforderlich: Funktioniert mit <form method="POST"> aus der Box
  • Standardzugriff: Verwendung document.getElementById('editor').value genau wie eine normale Eingabe.
  • Backend-Agnostik: Funktioniert mit jedem Backend (Python, Node.js, PHP usw.) wie ein normales Formularfeld

MarkdownEditor vs. EasyMDE / SimpleMDE

Die meisten JavaScript-Markdown-Editoren (EasyMDE, SimpleMDE, CodeMirror-basierte Editoren) verstecken Ihre <textarea> und bearbeiten Sie eine Kopie und schreiben Sie den Inhalt zurück, wenn das Formular gesendet wird. Das funktioniert, bis etwas anderes den Wert benötigt: a required Das Feld, auf das sich der Browser nicht konzentrieren kann, blockiert die Übermittlung vollständig und .value oder FormData Vor dem Senden lesen gibt eine leere Zeichenfolge zurück, die Htmx-, Turbo-, Autosave- und nicht gespeicherte Änderungswächter unterbricht. MarkdownEditor ist anders. Er formatiert den Textbereich, den Sie bereits haben, und belässt ihn als das Feld, in das Sie eingeben, sodass der Wert jederzeit korrekt ist.

BesonderheitMarkdownEditorEasyMDE / SimpleMDE
Nativer Textbereich bleibt erhalten✅❌ Versteckt, als Kopie bearbeitet
Funktioniert mit required Felder✅❌ Browser blockiert das Absenden
.value Vor dem Absenden korrigieren✅❌ Leer, bis das Formular gesendet wird
Serialisiert mit FormData, htmx, Turbo✅❌ Benötigt die eigene API des Editors
WYSIWYG-Hybridmodus✅❌
Integriertes Suchen und Ersetzen✅❌
RTL-Unterstützung✅ EingebautÜber CodeMirrors direction Option
Inline-Ereignishandler (CSP)✅ KeineManche
Dunkler Modus / Thematisierung✅Beschränkt
Bundle-Größe, komprimiert53 KB107 KB (JS + CSS)

Framework-Integration

Weil MarkdownEditor das Native beibehält <textarea>Es lässt sich ohne zusätzlichen Code in jedes Backend-Framework integrieren. Ihr Server empfängt den Markdown-Inhalt genau so, wie er es von jedem Standardformularfeld tun würde. Für React und Vue sind einige Zeilen erforderlich, die am Ende dieses Abschnitts behandelt werden.

Django

Fügen Sie ein hinzu class zu Ihrem Textbereichs-Widget und initialisieren Sie den Editor: request.POST['content'] Funktioniert ohne zusätzliche Schritte.

python
1
2
3
4
5
6
7
8
# forms.py
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['content']
        widgets = {
            'content': forms.Textarea(attrs={'class': 'markdown-editor'}),
        }
javascript
1
2
new MarkdownEditor('.markdown-editor');
// request.POST['content'] contains the markdown on submit

Laravel

Verwenden f.text_area mit einer Klasse: $request->input('content') erhält den Abschlag direkt.

html
1
2
<textarea name="content" class="markdown-editor">{{ old('content') }}</textarea>
<script>new MarkdownEditor('.markdown-editor');</script>

Ruby auf Schienen

Funktioniert mit form_with sofort einsatzbereit: params[:content] enthält den Abschlag. Für Turbo Drive verwenden Sie turbo:load anstatt DOMContentLoaded.

javascript
1
2
3
4
5
6
document.addEventListener('turbo:load', () => {
    document.querySelectorAll('.markdown-editor:not([data-mde-init])').forEach(el => {
        el.setAttribute('data-mde-init', 'true');
        new MarkdownEditor(el);
    });
});

Node.js / Express

req.body.content erhält den Abschlag beim Absenden des Formulars: kein Synchronisierungsschritt, keine benutzerdefinierte Extraktion.

html
1
2
3
<textarea name="content" class="markdown-editor"></textarea>
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>new MarkdownEditor('.markdown-editor');</script>

PHP

$_POST['content'] funktioniert genau wie mit jedem Standard-Textbereich: Fügen Sie es ein und Ihre vorhandene Formularverarbeitung erfordert keine Änderungen.

html
1
2
3
4
5
6
<form method="POST" action="save.php">
  <textarea name="content" class="markdown-editor"></textarea>
  <button type="submit">Save</button>
</form>
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
<script>new MarkdownEditor('.markdown-editor');</script>

Reagieren

Erstellen Sie den Editor in einem Effekt und zerstören Sie ihn beim Unmounten. Verwenden defaultValue statt value: Der Editor schreibt direkt in den Textbereich, sodass eine kontrollierte Bindung die Eingaben des Benutzers überschreiben würde.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { useEffect, useRef } from 'react';
import MarkdownEditor from 'markdown-text-editor';

function MarkdownField({ name, defaultValue = '', onChange }) {
    const ref = useRef(null);

    useEffect(() => {
        const editor = new MarkdownEditor(ref.current, { onChange });
        return () => editor.destroy();
    }, []);

    return &lt;textarea ref={ref} name={name} defaultValue={defaultValue} /&gt;;
}

Rückkehr editor.destroy() Der Effekt deckt auch StrictMode ab, der Effekte in der Entwicklung zweimal ausführt und andernfalls zwei Editoren auf einem Textbereich belassen würde. Das leere Abhängigkeitsarray ist beabsichtigt: Optionen werden einmal gelesen, wenn der Editor erstellt wird, sodass eine erneute Ausführung des Effekts ihn zerstören und bei jeder Änderung neu erstellen würde.

Vue

Gleiche Idee. Legen Sie den Anfangswert einmal fest onMounted und nicht binden :value, oder jeder Tastendruck, der zurück ausgegeben wird v-model würde den Textbereich überschreiben.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
&lt;script setup&gt;
import { ref, onMounted, onBeforeUnmount } from 'vue';
import MarkdownEditor from 'markdown-text-editor';

const el = ref(null);
const props = defineProps({ modelValue: { type: String, default: '' } });
const emit = defineEmits(['update:modelValue']);
let editor = null;

onMounted(() => {
    el.value.value = props.modelValue;
    editor = new MarkdownEditor(el.value, {
        onChange: value =&gt; emit('update:modelValue', value)
    });
});

onBeforeUnmount(() =&gt; editor?.destroy());
&lt;/script&gt;

&lt;template&gt;&lt;textarea ref="el"&gt;&lt;/textarea&gt;&lt;/template&gt;

Verwendet als <MarkdownField v-model="content" />. In einfacher Form können Sie überspringen v-model vollständig und lesen Sie den Wert aus dem Textbereich beim Senden, wie bei jedem anderen Framework.

Konfiguration

Sie können das Verhalten und die Benutzeroberfläche des Editors vollständig anpassen, indem Sie eine übergeben options Objekt. Wenn Sie eine Option weglassen, wird der Standardwert verwendet.

Optionen werden einmal gelesen, wenn der Editor erstellt wird. Eine nachträgliche Änderung hat keine Auswirkung: Anruf destroy() und erstellen Sie stattdessen einen neuen Editor.

EigentumTypStandardZweck
modestring'plain'Legt die anfängliche Ansicht fest. Verwenden Sie Hybrid für ein WYSIWYG-Erlebnis oder Plain für reine Syntax.
placeholderstring'Write...'Text, der angezeigt wird, wenn der Editor leer ist.
toolbararray[...]Definiert, welche Werkzeuge in welcher Reihenfolge angezeigt werden.
footerfalsch | Objektalles sichtbarSteuert die Statusleiste, die unterhalb des Editors angezeigt wird. Stellen Sie auf ein false um es ganz auszublenden oder ein Objekt zu übergeben, um einzelne Statistiken umzuschalten.
themestringinheritedLegt explizit das Editor-Thema fest (hell, dunkel, schneebeere, dunkelbeere). Wenn es weggelassen wird, erbt der Editor data-theme vom nächsten Vorfahrenelement oder dem <textarea> selbst.
minHeightnumber200Mindesthöhe in Pixel, auf die der Editor verkleinert wird, wenn der Inhalt kurz ist. Passt zu maxHeight , um den Bereich für die automatische Vergrößerung festzulegen.
maxHeightnumber500Maximale Höhe in Pixel, auf die der Editor im Nicht-Vollbildmodus wachsen kann. Sobald der Inhalt diese Höhe überschreitet, erscheint im Editor eine Bildlaufleiste. Der Editor verfügt außerdem über einen Ziehgriff, sodass Benutzer die Größe manuell über diese Grenze hinaus ändern können.
rendererfunctionmarkedErsetzt den für die Vorschau verwendeten Markdown-Parser. Empfängt die Markdown-Zeichenfolge und muss eine HTML-Zeichenfolge zurückgeben.
sanitizerfunctionDOMPurifyErsetzt den HTML-Sanitizer. Empfängt den gerenderten HTML-Code und muss den sicheren HTML-Code zur Anzeige zurückgeben.
onChangefunctionundefinedBei jeder Inhaltsänderung wird ein Rückruf ausgelöst: Eingabe, Aktionen in der Symbolleiste, Rückgängigmachen/Wiederherstellen und Fortsetzung der Liste. Empfängt den aktuellen Markdown-String als einziges Argument.

🛠 Anpassung der Symbolleiste

Die Symbolleiste ist modular aufgebaut. Durch Modifizieren des Arrays können Sie ein minimales Erlebnis oder eine leistungsstarke Suite mit vollem Funktionsumfang schaffen.

Verfügbare Tools

KategorieWerkzeugschlüssel
Typografieheading, bold, italic, strikethrough, blockquote
Listenul (bullet), ol (numbered), checklist
Codecode (im Einklang), codeblock (eingezäunter Block)
Einlagenhr (horizontale Regel), table (Tabellenvorlage)
Medienlink, image
Bearbeitungundo, redo, indent, outdent
Sichtpreview
Vorlagen{ variables: [...] }, inline konfiguriert

Werkzeugreferenz

WerkzeugBeschreibung
headingÖffnet ein Dropdown-Menü zur Auswahl der Überschriftenebene H1–H6
boldAktiviert die fette Textformatierung.
italicAktiviert die kursive Textformatierung.
strikethroughErmöglicht das Durchstreichen von Text.
ol(Geordnete Liste): Konvertiert Text in ein nummeriertes Listenformat.
ul(Ungeordnete Liste): Wandelt Text in eine Aufzählungspunktliste um.
checklistFügt Ihrem Text Kontrollkästchen hinzu, wodurch er sich hervorragend für Aufgaben, To-Do-Listen oder die Verfolgung des Abschlussstatus eignet.
blockquoteMarkieren Sie zitierten oder hervorgehobenen Text.
codeUmschließt ausgewählten Text für Inline-Code in einzelne Backticks. Durch erneutes Klicken werden die Backticks entfernt.
codeblockUmschließt ausgewählten Text in einen umzäunten Codeblock mit drei Backticks. Durch erneutes Klicken werden die Zäune entfernt.
hrFügt ein --- horizontale Linie an der Cursorposition in einer eigenen Zeile.
tableFügt an der Cursorposition eine Starter-2x3-Markdown-Tabellenvorlage ein.
imageErmöglicht das Einfügen von Bildern über die Markdown-Syntax.
linkErmöglicht das Hinzufügen von Hyperlinks zu Ihrem Text.
undoUm die letzten Änderungen rückgängig zu machen.
redoUm die letzten rückgängig gemachten Änderungen erneut anzuwenden.
indentUm die Einrückungsebene zu erhöhen.
outdentZum Verringern der Einrückungsstufe.
previewSchaltet eine Vollbild-Vorschau nebeneinander um. Kontrollkästchen im Vorschaubereich sind anklickbar und aktualisieren die Markdown-Quelle sofort. Drücken Sie Escape, um den Vollbildmodus zu verlassen. Wenn ein fester Header den Editor im Vollbildmodus abdeckt, siehe --mte-fullscreen-z-index.
💡 Umsetzungstipps:
  • Neuordnung: Die Schaltflächen werden genau in der Reihenfolge angezeigt, in der Sie sie im Array auflisten
  • Entfernen: Lassen Sie einfach einen beliebigen Schlüssel weg (z image) aus dem Array, um diese Funktion für den Benutzer vollständig zu deaktivieren
  • Nativer Fallback: Wenn Sie keinen bereitstellen placeholder In JS verwendet das Plugin automatisch das placeholder Attribut aus Ihrem HTML <textarea>

📊 Fußzeile (Statusleiste)

Die Fußzeile befindet sich unterhalb des Editors und zeigt die Zeile, Spalte des Cursors, die Zeichenanzahl des Dokuments und optional die Wortanzahl an, alles in Echtzeit aktualisiert. Es ist standardmäßig sichtbar und jede Statistik kann unabhängig umgeschaltet werden.

SchlüsselTypStandardBeschreibung
linebooleantrueZeigt die aktuelle Zeilennummer an.
colbooleantrueZeigt die aktuelle Spaltennummer an.
charsbooleantrueZeigt die Gesamtzahl der Zeichen an.
wordsbooleanfalseZeigt die Gesamtzahl der Wörter an. Standardmäßig deaktiviert: auf eingestellt true zu ermöglichen.

Anwendungsbeispiele

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// Default — line, col, and chars visible
new MarkdownEditor('#editor');

// Disable the footer entirely
new MarkdownEditor('#editor', { footer: false });

// Hide only character count
new MarkdownEditor('#editor', { footer: { chars: false } });

// Hide line and column, keep character count
new MarkdownEditor('#editor', { footer: { line: false, col: false } });

// Show only line number
new MarkdownEditor('#editor', { footer: { col: false, chars: false } });

// Enable word count alongside the defaults
new MarkdownEditor('#editor', { footer: { words: true } });

// Show word count only
new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } });

🔀 Bearbeitungsmodi

MarkdownEditor bietet zwei verschiedene Möglichkeiten zum Schreiben und Formatieren Ihrer Inhalte. Sie können zwischen einer traditionellen syntaxorientierten Ansicht und einem modernen, visuell ausgerichteten Erlebnis wechseln.

  • plain (Standard*): Eine saubere, leistungsstarke Markdown-Umgebung, in der Syntax (wie **bold** oder # heading) ist sichtbar. Ideal für Entwickler und Markdown-Puristen
  • hybrid: Ein WYSIWYG-inspiriertes Erlebnis, das Formatierungen (Fett, Kursiv, Überschriften) in Echtzeit während der Eingabe wiedergibt und gleichzeitig die zugrunde liegende Markdown-Struktur beibehält.
javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Default initialization (Plain Mode)
new MarkdownEditor('#markdown-editor');

// Explicit Plain Mode
new MarkdownEditor('#markdown-editor', {
    mode: 'plain'
});

// Hybrid (Visual) Mode
new MarkdownEditor('#markdown-editor', {
    mode: 'hybrid'
});

Vorschau des Hybrid- und Normalmodus:

Hybridmodus

Visuelle Formatierungen werden während der Eingabe in Echtzeit gerendert.

Einfacher Modus (Standard)

Konzentriert sich auf die reine Markdown-Syntax für ein unkompliziertes Erlebnis.

🌙 Thematisierung

MarkdownEditor erbt sein Thema automatisch von der umgebenden Seite: keine Konfiguration erforderlich. Der Herausgeber liest data-theme vom nächsten Vorfahren bei der Initialisierung, so dass es sofort mit dem Thema Ihrer Website synchronisiert bleibt.

Wie das Thema gelöst wird (Prioritätsreihenfolge)

  1. theme Option: explizite Überschreibung im Optionsobjekt übergeben
  2. data-theme auf der <textarea>: direkt auf das Element setzen
  3. data-theme auf einem beliebigen Vorfahren: z.B. <html>, <body>, oder ein Wrapper <div>

Verfügbare Themen

'light' (Standard), 'dark', 'snowberry', 'darkberry'

Option 1, erben von <html> oder ein beliebiger Vorfahre (keine Konfiguration)
html
1
2
3
4
5
6
<html data-theme="dark">
  ...
  <textarea id="markdown-editor"></textarea>
  <script>
    new MarkdownEditor('#markdown-editor'); // picks up dark automatically
  </script>
Option 2: einstellen data-theme direkt am <textarea>
html
1
2
3
4
<textarea id="markdown-editor" data-theme="dark"></textarea>
<script>
  new MarkdownEditor('#markdown-editor');
</script>
Option 3: explizit theme Option (überschreibt alles)
javascript
1
2
3
new MarkdownEditor('#markdown-editor', {
    theme: 'dark'
});

🎨 Benutzerdefiniertes Theme über CSS-Variablen

Sie können das Erscheinungsbild des Editors vollständig anpassen, indem Sie seine CSS-Variablen überschreiben .markdown-editor-wrapper Element oder irgendein [data-theme] Wähler. Alle Farben verwenden das OKLCH-Farbraum für wahrnehmungsmäßig einheitliche Ergebnisse.

VariableZweckLichtstandardDunkle Standardeinstellung
--color-baseHintergrund des Herausgebersoklch(100% 0 0)oklch(10.9% 0 0)
--color-on-basePrimäre Textfarbeoklch(22% 0 0)oklch(98% 0 0)
--color-primaryPrimärer Akzent (Symbolleiste aktiv, Links)oklch(51.1% .262 277)oklch(66.4% .184 286)
--color-on-primaryText auf primärfarbigen Oberflächenoklch(96.2% .018 272)oklch(10% .01 270)
--color-secondarySekundärer Akzentoklch(59.1% .293 323)oklch(65% .18 220)
--color-accentHervorhebungsakzent (Inline-Code, kursiv)oklch(54.1% .281 293)oklch(75% .18 50)
--color-neutralNeutrale Flächen (Ränder, Trennwände)oklch(15% 0 0)oklch(85% 0 0)
--color-errorFarbe des Fehlerstatusoklch(57.7% .245 27)oklch(60% .22 30)
--border-radiusEckenabrundung des Editorrahmens0.25rem
Beispiel für ein benutzerdefiniertes Theme

Überschreiben Sie alle Variablen .markdown-editor-wrapper nach der Initialisierung des Editors oder definieren Sie eine benutzerdefinierte Datei [data-theme] Block in Ihrem Stylesheet:

css
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/* Override individual variables */
.markdown-editor-wrapper {
    --color-primary: oklch(60% 0.2 30);   /* orange accent */
    --border-radius: 0.5rem;
}

/* Or define a full custom theme */
[data-theme="brand"] .markdown-editor-wrapper,
.markdown-editor-wrapper[data-theme="brand"] {
    --color-base:       oklch(15% 0.01 250);
    --color-on-base:    oklch(95% 0 0);
    --color-primary:    oklch(65% 0.22 145);   /* green */
    --color-on-primary: oklch(10% 0 0);
    --color-accent:     oklch(75% 0.18 60);
    --color-neutral:    oklch(80% 0 0);
    --border-radius:    0.75rem;
}
javascript
new MarkdownEditor('#markdown-editor', { theme: 'brand' });

🏷 Variablen

Fügt ein Dropdown-Menü in der Symbolleiste zum Einfügen von Platzhaltern hinzu. Nützlich, wenn die Person, die ein Dokument schreibt, nicht der Entwickler ist, der die Platzhaltersyntax definiert hat, wie bei E-Mail-, Rechnungs- oder Vertragsvorlagen: Sie wählt einen lesbaren Namen und die richtige Syntax wird für sie eingefügt.

javascript
1
2
3
4
5
6
7
8
9
new MarkdownEditor('#markdown-editor', {
    toolbar: ['bold', 'italic', 'link',
        { variables: [
            { label: 'Customer Name', value: '{{customer.name}}' },
            { label: 'Invoice No',    value: '{{invoice.number}}' }
        ]},
        'preview'
    ]
});

Das Tool wird inline im konfiguriert toolbar Array, sodass die Position zwischen den anderen Schaltflächen Ihnen überlassen bleibt. Die Schaltfläche listet die Beschriftungen auf, und wenn Sie auf eine klicken, werden diese eingefügt value am Cursor und ersetzt jede Auswahl. Wenn die Liste leer ist, wird nichts gerendert.

Beispielwerte in der Vorschau

Ein Eintrag gegeben a sample zeigt dieses Beispiel in der Vorschau an, während der Textbereich den echten Platzhalter behält. Einträge ohne eins erscheinen wie geschrieben, Sie können also beides mischen.

javascript
1
2
3
4
5
6
7
{ variables: [
    { label: 'Customer Name', value: '{{customer.name}}', sample: 'Hannes' },
    { label: 'Invoice No',    value: '{{invoice.number}}' }
]}

// textarea : Hi {{customer.name}}, invoice {{invoice.number}}
// preview  : Hi Hannes, invoice {{invoice.number}}

Gruppierung

Geben Sie einen Eintrag ein items statt eines value um einen Abschnitt mit Überschrift darzustellen. Gruppierte und flache Einträge können in einer Liste gemischt werden.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{ variables: [
    { label: 'Today', value: '{{today}}', sample: '10 September 2026' },
    { label: 'Customer', items: [
        { label: 'Name',  value: '{{customer.name}}',  sample: 'Hannes' },
        { label: 'Email', value: '{{customer.email}}', sample: 'hannes@example.com' }
    ]},
    { label: 'Invoice', items: [
        { label: 'Number', value: '{{invoice.number}}' }
    ]}
]}

Wissenswertes

  • Der Editor löst niemals Variablen auf. Er fügt Text ein und Ihre Anwendung ersetzt später reale Werte, normalerweise serverseitig. sample wirkt sich nur darauf aus, was in der Vorschau angezeigt wird.
  • Beschriftungen werden als einfacher Text angezeigt, daher wird das Markup in einer Beschriftung nie gerendert.
  • Fehlerhafte Einträge werden übersprungen statt ausgelöst, und die Schaltfläche wird überhaupt nicht gerendert, wenn nichts Verwendbares konfiguriert ist.

🖋 Benutzerdefinierter Renderer

Die Vorschau wird mit gerendert markiert und desinfiziert mit DOMPurify. Beide können ausgetauscht werden. Verwenden Sie diese Option, wenn Ihre Anwendung Markdown bereits mit einer anderen Bibliothek rendert und Sie möchten, dass die Vorschau genau mit der Produktion übereinstimmt.

Bei beiden Optionen handelt es sich um einfache Funktionen, die einen String annehmen und zurückgeben, sodass jeder Parser und jedes Sanitizer funktioniert.

javascript
1
2
3
4
5
6
7
8
9
import MarkdownIt from 'markdown-it';
import taskLists from 'markdown-it-task-lists';
import MarkdownEditor from 'markdown-text-editor';

const md = new MarkdownIt({ linkify: true, breaks: true }).use(taskLists);

new MarkdownEditor('#markdown-editor', {
    renderer: markdown => md.render(markdown)
});

DOMPurify wird weiterhin auf der Ausgabe ausgeführt, sodass Sie den XSS-Schutz beibehalten, ohne etwas konfigurieren zu müssen.

Benutzerdefiniertes Desinfektionsmittel

Wird nur benötigt, wenn die Standardeinstellung etwas entfernt, das Ihr Renderer ausgibt. DOMPurify entfernt <iframe> standardmäßig, daher muss es für Videoeinbettungen explizit zugelassen werden. DOMPurify muss in Ihren eigenen Code importiert werden, da die mit dem Editor gebündelte Kopie intern ist.

javascript
1
2
3
4
5
6
7
8
9
import DOMPurify from 'dompurify';

new MarkdownEditor('#markdown-editor', {
    renderer:  markdown => md.render(markdown),
    sanitizer: html => DOMPurify.sanitize(html, {
        ADD_TAGS: ['iframe'],
        ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder']
    })
});

Laden Sie DOMPurify mit einem Skript-Tag anstelle eines Bundlers zusammen mit dem Editor:

html
1
2
<script src="https://cdn.jsdelivr.net/npm/dompurify"></script>
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>

Wissenswertes

  • Nur Vorschau. Die Live-Formatierung des Hybridmodus verwendet einen separaten internen Renderer und ist nicht betroffen.
  • Aufgabenlisten benötigen Plugin-Unterstützung. Anklickbare Kontrollkästchen werden durch Suchen gefunden input[type="checkbox"] in der Ausgabe, daher ist ein Abschlag erforderlich markdown-it-task-lists. Der Editor protokolliert eine Warnung, wenn er die Aufgabenlistensyntax und keine Kontrollkästchen erkennt.
  • Beide müssen synchron sein und einen String zurückgeben. Ein async Funktion schreibt [object Promise] in die Vorschau.
  • Der Austausch des Desinfektionsmittels ersetzt Ihren Schutz. Eine Durchreiche wie z.B html => html deaktiviert die Bereinigung vollständig und ist nur für vollständig vertrauenswürdige Inhalte sicher.

🎨 Interne Elemente gestalten

CSS-Variablen decken die meisten Themen ab, da sie erben. Setzen Sie also eine Variable ein .markdown-editor-wrapper erreicht die Symbolleiste, Schaltflächen, Vorschau und Fußzeile. Greifen Sie nur dann nach einem Klassennamen, wenn keine Variable das bereitstellt, was Sie benötigen.

css
1
2
3
4
5
/* Variables set on the wrapper inherit down to every child */
.markdown-editor-wrapper {
    --border-radius: 12px;   /* rounds the editor and its toolbar buttons */
    --color-primary: oklch(60% 0.2 30);
}

Klassenreferenz

Diese Klassennamen sind stabil und können sicher verwendet werden.

KlasseElement
.markdown-editor-wrapperÄußerer Container, der den gesamten Editor umschließt
.toolbarSymbolleiste über dem Bearbeitungsbereich
.markdown-btnIndividuelle Schaltfläche in der Symbolleiste
.preview-btnDie Schaltfläche zum Umschalten zwischen Vorschau und Vollbild
.editor-layoutRaster, das den Bearbeitungsbereich und die Vorschau nebeneinander enthält
.textarea-wrapperWrapper um den Bearbeitungsbereich
.editor-textareaDas zugrunde liegende Textbereichselement
.display-layerGerenderte Formatierungsebene, nur Hybridmodus
.preview-wrapperVorschauspalte
.preview-contentGerenderter Markdown in der Vorschau
.editor-footerStatusleiste unterhalb des Editors
.find-replace-panelPanel suchen und ersetzen
css
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/* Some variables are set by the component on itself, which beats an
   inherited value. Target the element directly for those. */
.markdown-editor-wrapper .markdown-btn {
    --btn--font-size: 0.875rem;
}

/* And use classes for anything no variable exposes */
.markdown-editor-wrapper .toolbar {
    border-bottom: 2px solid oklch(60% 0.2 30);
}

Ausrichtung auf einen Redakteur

Wenn Sie mehrere Redakteure auf einer Seite haben, zielen Sie auf einen von ihnen ab data-editor. Der Wrapper spiegelt seine ID wider <textarea>, Also <textarea id="notes"> gibt dir [data-editor="notes"]. Die ID selbst bleibt also im Textbereich getElementById funktioniert weiter.

css
1
2
3
4
/* one editor only */
[data-editor="notes"] {
    --border-radius: 0;
}

🪟 Vollbild & Layering (Z-Index)

Im Vollbildmodus verwendet der Editor z-index: 10000, wodurch die Ebenen gelöscht werden, die die meisten UI-Frameworks für feste Header und Overlays reservieren. Wenn der Editor immer noch von einer festen Kopfzeile oder Seitenleiste abgedeckt wird, erhöhen Sie diesen Wert.

Überschreiben Sie es mit --mte-fullscreen-z-index. Der Wert gilt nur im Vollbildmodus und erbt. Wenn Sie ihn also auf einen beliebigen Vorfahren festlegen, werden alle darunter liegenden Editoren abgedeckt.

css
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/* every editor on the page */
.markdown-editor-wrapper {
    --mte-fullscreen-z-index: 20000;
}

/* one section only - the value inherits down */
#admin-panel {
    --mte-fullscreen-z-index: 20000;
}

/* a single editor, by its textarea id */
[data-editor="notes"] {
    --mte-fullscreen-z-index: 20000;
}

Inhalts-API

Eine der Kernstärken von MarkdownEditor besteht darin, dass es das zugrunde liegende behält <textarea> perfekt synchronisiert. Ganz gleich, ob Sie ein modernes JavaScript-Framework oder ein traditionelles Backend wie Django, PHP oder Laravel verwenden, der Workflow bleibt einfach und nativ.

Inhalte lesen und schreiben

1. The Native Way (empfohlen)

Da der Editor einen Standardtextbereich erweitert, können Sie bekannte DOM-Methoden verwenden. Dies ist der schnellste Weg, mit Ihren Daten zu interagieren, ohne eine neue API zu erlernen.

javascript
1
2
3
4
5
// Retrieve content via ID
const markdown = document.getElementById('markdown-editor').value;

// Set content via ID (The editor UI updates automatically)
document.getElementById('markdown-editor').value = "# New Heading Content";

2. Verwenden einer Variablenreferenz

Wenn Sie einen Verweis auf das Textarea-Element haben, können Sie es direkt verwenden: Es ist keine bibliotheksspezifische API erforderlich.

javascript
1
2
3
4
5
6
7
const textarea = document.getElementById('markdown-editor');

// Retrieve content
const markdown = textarea.value;

// Set content (the editor UI reflects this immediately)
textarea.value = "## Updated via JS";

3. Festlegen des anfänglichen Inhalts serverseitig

Die empfohlene Methode zum Festlegen des anfänglichen Inhalts ist direkt im <textarea> HTML: Dies funktioniert natürlich mit jedem Backend-Framework (Django, Laravel, Rails, PHP usw.) und der Editor rendert es automatisch bei init.

html
1
2
<!-- Recommended: set content server-side -->
<textarea id="markdown-editor"># Hello World</textarea>

Um Inhalte zur Laufzeit zu lesen oder zu aktualisieren, verwenden Sie die native textarea Wert. Anruf editor.render() nach einem Update, um die Vorschau- und Hybridebene zu aktualisieren.

javascript
1
2
3
4
5
6
7
8
const textarea = document.getElementById('markdown-editor');

// Read
const markdown = textarea.value;

// Update at runtime
textarea.value = '# New content';
editor.render();

4. Abbau des Editors: destroy()

Anruf editor.destroy() um den Editor-DOM-Wrapper zu entfernen und das Original wiederherzustellen <textarea> an seine Position im Dokument. Nützlich in Single-Page-Anwendungen beim Unmounten einer Ansicht.

javascript
1
2
3
4
const editor = new MarkdownEditor('#markdown-editor');

// Remove the editor and restore the plain textarea
editor.destroy();

Auf Veränderungen reagieren mit onChange

Übergeben Sie eine onChange Rückruf, um bei jeder Inhaltsänderung benachrichtigt zu werden. Empfängt die aktuelle Markdown-Zeichenfolge.

javascript
1
2
3
4
5
const editor = new MarkdownEditor('#markdown-editor', {
    onChange(value) {
        console.log('Content changed:', value.length, 'characters');
    }
});

Entwurf automatisch speichern mit localStorage

Verwenden onChange um bei jedem Tastendruck einen Entwurf zu speichern. Stellen Sie es wieder her, indem Sie den Textbereich vorab ausfüllen, bevor Sie den Editor initialisieren.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const DRAFT_KEY = 'my-page-draft';

// Restore saved draft before init (only if textarea starts empty)
const textarea = document.getElementById('markdown-editor');
const saved = localStorage.getItem(DRAFT_KEY);
if (saved && !textarea.value) textarea.value = saved;

// Save on every change
const editor = new MarkdownEditor('#markdown-editor', {
    onChange(value) {
        localStorage.setItem(DRAFT_KEY, value);
    }
});

// Clear draft after successful form submission
document.querySelector('form').addEventListener('submit', () => {
    localStorage.removeItem(DRAFT_KEY);
});

Formularübermittlung

Weil MarkdownEditor direkt auf dem nativen basiert <textarea>Es ist sofort mit jedem Backend-Framework (Django, Laravel, PHP, Ruby on Rails usw.) kompatibel.

Hier kommt die „Native-First“-Philosophie zum Tragen. Sie müssen die Daten vor dem Absenden eines Formulars nicht manuell synchronisieren. Der Browser behandelt den Editor genau wie ein Standard-Eingabefeld.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<form method="POST" action="/api/submit">
  <textarea id="markdown-editor" name="content" class="h-48" rows="5">
    # Initial Content
  </textarea>

  <button type="submit">Submit to Server</button>
</form>

<script>
  // Just initialize it. That's it.
  new MarkdownEditor('#markdown-editor');
</script>

Notiz: Initialisierung des MarkdownEditor-Plugins erforderlich

Verwenden Sie einfach ein Standard-HTML <form>. Der name Das Attribut im Textbereich wird von Ihrem Server verwendet, um den Inhalt zu identifizieren.

🚀 Warum es ein Game-Changer für Backends ist

Da der Herausgeber das Native bewahrt <textarea> Verhalten verarbeitet Ihr Server die Daten als Standardzeichenfolge. Es ist keine zusätzliche Logik erforderlich: Nein preventDefault() und kein Handbuch FormData Konstruktion.

💡 Warum dies ein „Killer-Feature“ ist:

Die meisten Editoren (wie Quill, Editor.js, simpleMDE, easyMDE) speichern Daten in komplexen JSON-Strukturen. Wenn ein Entwickler diese verwendet, muss er sein Datenbankschema und seine Rendering-Logik neu schreiben.

Mit MarkdownEditor kann ein Entwickler eine alte Website durch eine einfache ersetzen <textarea> mit Ihrem Editor, und das Backend weiß nicht einmal, dass es sich geändert hat. Es erhält einfach den gleichen Rohtext wie immer, aber der Benutzer erhält ein zehnmal besseres Erlebnis.

Rahmen / SpracheSo greifen Sie auf den Markdown-Inhalt zu
PHP$_POST['content']
Djangorequest.POST.get('content')
Node.js (Express)req.body.content
Laravel$request->input('content')
Ruby auf Schienenparams[:content]

🖼️ Erweiterter Bild-Upload

Die native Handhabung von Bild-Uploads: Anstatt sich auf langsame, speicherintensive Base64-Strings zu verlassen, ist dies ein erheblicher Gewinn für Leistung und SEO.

Konfigurationsoptionen

Das Bildtool unterstützt a fileInput Konfiguration für direkte Server-Uploads.

  • accept: Definieren Sie ein Array zulässiger Bildformate (z. B. „webp“, „avif“).
  • uploadUrl: Geben Sie den Backend-Endpunkt an, an dem die File Das Objekt wird per gesendet POST
  • params: Optionales Objekt zum Senden zusätzlicher Daten (wie CSRF-Tokens, Benutzer-IDs oder Ordnernamen) zusammen mit der Bilddatei

Anwendungsbeispiel (Vollständige Konfiguration)

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const options = {
  placeholder: 'Start writing...',
  toolbar: [
    'link',
    {
      image: {
        fileInput: {
            accept: ['webp', 'avif'], // restrict the image upload format
            uploadUrl: '/api/upload', // Your upload endpoint
            params: {
                _token: 'your_csrf_token_here', // Essential for Laravel/Django
                folder: 'blog_posts'
            }
        },
        // Supports boolean: true/false OR object: { required: true }
        altInput: { required: true }
      }
    },
    'preview'
  ],
}
const editor = new MarkdownEditor('#markdown-editor', options);

📡 Serverintegration

Die Anfrage

Der Herausgeber sendet eine POST Anfrage als multipart/form-data. Standardmäßig umfasst es:

  • image_file: Das eigentliche Dateiobjekt
  • image_alt: Der vom Benutzer eingegebene Alternativtext
  • ... plus alle in der definierten benutzerdefinierten Daten params Objekt

Die erforderliche Antwort

Um einen erfolgreichen Upload zu bestätigen und das Bild in den Editor einzufügen, muss Ihr Server die folgende JSON-Struktur zurückgeben:

json
1
2
3
4
{
  "success": true,
  "image_path": "https://cdn.yourdomain.com/uploads/image.webp"
}

Hinweis: Stellen Sie sicher, dass Sie den Schlüssel verwenden image_path für die URL des hochgeladenen Bildes.

Bild-Alt-Text-Validierung (altInput)

Um sicherzustellen, dass Ihre Inhalte zugänglich und SEO-freundlich bleiben, erzwingt MarkdownEditor standardmäßig die Alt-Text-Validierung.

  • Standardverhalten: Wenn altInput ist nicht definiert, der Standardwert ist { required: true }
  • Barrierefreiheit erzwingen: Benutzer können kein Bild einfügen, bis eine Alternativbeschreibung bereitgestellt wird

1. Standard (keine Konfiguration erforderlich)

javascript
1
2
3
4
// Alt text is REQUIRED by default
image: {
  fileInput: { uploadUrl: '/api/upload' }
}

2. Kurzschrift (Validierung deaktivieren)

Wenn Sie Bilder ohne Beschreibung zulassen möchten, setzen Sie einfach den booleschen Wert auf false.

javascript
1
2
3
image: {
  altInput: false // Users can now skip the alt text field
}

3. Objektbasiert (explizit)

javascript
1
2
3
4
5
image: {
    altInput: {
        required: false // Disables alt text validation — users can skip the alt field
    }
}

Standardbildnutzung (Nr fileInput)

Wenn fileInput nicht konfiguriert ist, verwendet der Editor standardmäßig ein einfaches URL-basiertes Modal. Dies ist ideal, wenn Ihre Benutzer hauptsächlich auf externe Image-Hosts verlinken.

javascript
1
2
3
4
5
6
7
8
const options = {
  toolbar: [
    'link',
    'image',
    'preview'
  ],
}
const editor = new MarkdownEditor('#markdown-editor', options);

💡 Warum Parameter verwenden?

In Frameworks wie Laravel oder Django können Sie keine Dateien ohne CSRF-Token hochladen. Durch Hinzufügen _token zum params objekt, wird Ihre Anfrage nahtlos durch die Sicherheits-Middleware des Backends geleitet, wobei die "Zero Logic" -Philosophie für Ihre serverseitigen Controller beibehalten wird.

Tastaturkürzel

Gängige Formatierungsaktionen können direkt von der Tastatur aus ausgelöst werden, ohne die Symbolleiste zu berühren. Jede Verknüpfung wird auch im Tooltip der entsprechenden Symbolleistenschaltfläche angezeigt.

AbkürzungHandlung
Ctrl + B  /  ⌘ BUmschalten Fett
Ctrl + I  /  ⌘ IKursiv umschalten
Ctrl + K  /  ⌘ KLink einfügen
Ctrl + `  /  ⌘ `Inline umschalten Code
Ctrl + Shift + S  /  ⌘ ⇧ S~~Durchstreichen ~ ~ umschalten
Ctrl + 1  /  ⌘ 1Überschrift 1
Ctrl + 2  /  ⌘ 2Überschrift 2
Ctrl + 3  /  ⌘ 3Überschrift 3
Ctrl + L  /  ⌘ LAufzählungsliste umschalten
Ctrl + Z  /  ⌘ ZWiderrufen
Ctrl + Shift + Z  /  ⌘ ⇧ ZWiederholen
TabRücken Sie die ausgewählten Zeilen ein.
Shift + TabAusgewählte Zeilen übertreffen
Ctrl + F  /  ⌘ FFind-Panel öffnen
Ctrl + H  /  ⌘ HFenster Suchen & Ersetzen öffnen
Ctrl + Shift + F  /  ⌘ ⇧ FVollbild umschalten
F11Vollbild umschalten
EscapeFinde Panel schließen/Vollbildvorschau beenden

Suchen & Ersetzen

Ein integriertes Bedienfeld zum Suchen und Ersetzen ist im Editor verfügbar: Es ist keine Browsererweiterung oder ein separates Tool erforderlich.

  • Presseinformationen Ctrl + F (bzw. ⌘ F), um das Bedienfeld Suchen zu öffnen
  • Presseinformationen Ctrl + H (bzw. ⌘ H), um das Bedienfeld Suchen & Ersetzen zu öffnen
  • Die Suche ist **ohne Berücksichtigung der Groß- und Kleinschreibung * * und zeigt einen Live-Match-Zähler an (z. B. 3 von 12)
  • Navigieren Sie zu Übereinstimmungen mit den ▲/▼ -Buttons oder Enter / Shift + Enter
  • Ersetzen ersetzt die aktuell markierte Übereinstimmung; ** Alle ersetzen ** ersetzt jedes Ereignis auf einmal
  • Presseinformationen Escape um das Bedienfeld zu schließen und den Fokus wieder auf den Editor zu richten

Das Panel schwebt in der oberen rechten Ecke des Editor-Inhaltsbereichs und unterbricht das Schreiben nicht.

Funktionen

Integration 🔌 nativer Formulare

Funktioniert genau wie ein Standard <textarea>. Keine komplexen APIs: Verwenden Sie einfach die value oder name attribut. Es "funktioniert einfach" mit Standard-HTML-Formularübermittlungen in PHP, Django oder Node.js.

🖼️ Erweiterter Bild-Upload

Konfigurieren Sie native Server-Uploads über API. Vermeiden Sie schwere Base64-Zeichenfolgen, um schnellere Seitenladungen und überlegene SEO zu gewährleisten, indem Sie Bilder in Ihrem eigenen CDN hosten.

🔀 Hybrid- und einfache Modi

Wechseln Sie zwischen einem Hybrid (WYSIWYG) erfahrung für die visuelle Bearbeitung oder Einfacher Markdown modus für ein traditionelles Codierungsgefühl.

Hochleistung

A 53 KB gzipped bundle (252 KB minimiert, CSS inklusive) optimiert für "Heavy Content." Handhabt massive Dokumente und große Dateien ohne Eingabeverzögerung oder Leistungseinbußen. Entprellte Vorschau-Updates, zwischengespeicherte Stilberechnungen und konfliktfreies Tastaturhandling: Tab und Enter tun also immer genau eines.

Eingebaute Unterstützung

Muttersprachliche Unterstützung für Rechts-Links-Sprachen wie Arabisch, Urdu und Farsi. Perfekt für den Aufbau global zugänglicher Anwendungen.

Syntaxhervorhebung

Verbesserte Lesbarkeit mit klarem Code und Markdown-Formatierung.

🌙 Adaptive Thematisierung

Enthält Unterstützung für den automatischen Dunkelmodus. Es synchronisiert sich mit Ihren Systemeinstellungen oder dem Frutjam UI bibliothek für ein nahtloses visuelles Erlebnis.

📝 Intelligente Bearbeitung

Automatische Listenfortführung im GitHub-Stil für geordnete Listen, ungeordnete Listen und Checklisten: drücken Sie Enter und der Editor setzt das Muster fort. Kontrollkästchen im Vorschaufenster sind anklickbar und werden sofort mit der Markdown-Quelle synchronisiert.

Vollständig responsiv

Eine flüssige, mobile Benutzeroberfläche, die sich perfekt an Desktops, Tablets und Smartphones für die Bearbeitung unterwegs anpasst.

Universalhalter

Passend für ESM, UMD, CommonJS und IIFE. Arbeitet out of the box über CDN (<script src>), npm oder ein beliebiger Bündler (Vite, Webpack, Rollup): Keine zusätzliche Konfiguration erforderlich.

Zugänglich von Anfang an

Volle ARIA-UNTERSTÜTZUNG integriert: Symbolleiste Orientierungspunkt, beschrifteter Vorschaubereich, bildschirmleserfreundliche Schaltflächen, aria-pressed auf dem Vorschau-Schalter, disabled und aria-disabled auf inaktive Werkzeuge und korrigieren Sie die Fokuswiederherstellung, wenn Modale geschlossen werden.

🛡️ Keine CSS-Konflikte

Editor-Stile sind vollständig auf .markdown-editor-wrapper. Tailwinds globales Preflight ist ausgeschlossen, so dass der Editor sicher neben Bootstrap, Tailwind oder einem anderen Framework lebt, ohne seine Stile zu brechen.

Tastaturkürzel

Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S: gängige Formatierungsaktionen, ohne die Maus zu berühren. Jede Verknüpfung wird im Tooltip der Symbolleistenschaltfläche angezeigt.

Suchen & Ersetzen

Presse Ctrl+F zu finden oder Ctrl+H zum Öffnen von Suchen & Ersetzen. Suche ohne Berücksichtigung der Groß- und Kleinschreibung mit Live-Match-Zähler, Next/Prev-Navigation, Single Replace und Replace all: ohne den Editor zu verlassen.

🔒 XSS Safe Vorschau

Die gerenderte Vorschau wird über DOMPurify bevor er an den DOM geschrieben wurde. Skript-Tags, Inline-Ereignishandler und bösartige URLs in gestalteten Markdown-Eingaben werden automatisch entfernt: keine Konfiguration erforderlich.

Echtzeit-Vorschau

Sehen Sie, wie Ihr Markdown sofort gerendert wird, während Sie tippen.

Einfache Integration

Nahtlose Integration in jedes Webprojekt mit minimalem Setup.

🛠️ Anpassbare Symbolleiste

Konfigurieren und ordnen Sie Symbolleistenoptionen wie Fett, Kursiv und mehr dynamisch neu.

Konfigurationsbeispiel

Verwenden Sie dieses umfassende Beispiel, um *MarkdownEditor * mit allen primären Funktionen zu initialisieren, einschließlich benutzerdefinierter Symbolleistenreihenfolge und erweiterter Bild-Upload-Behandlung.

javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const editor = new MarkdownEditor('#markdown-editor', {
    mode: 'hybrid',
    placeholder: 'Start writing...',
    footer: {
        line: true,
        col: true,
        chars: true,
        words: true,
    },
    onChange(value) {
        console.log('Content updated:', value.length, 'characters');
    },
    toolbar: [
        'heading', 'bold', 'italic', 'strikethrough', 'blockquote',
        'ul', 'ol', 'checklist',
        'code', 'codeblock', 'hr', 'table',
        {
            image: {
                fileInput: {
                    accept: ['webp', 'avif', 'png'],
                    uploadUrl: '/api/upload'
                }
            }
        },
        'link', 'undo', 'redo', 'indent', 'outdent', 'preview'
    ],
});

// Read content natively
const markdown = document.getElementById('markdown-editor').value;

// destroy() when the view unmounts (SPAs)
// editor.destroy();

Fandest du das nützlich?

Ein GitHub-Stern hilft anderen Entwicklern, den Editor zu entdecken. Es ist Teil von Frutjam. Ein Stern dort hilft auch.

Geben Sie uns auf GitHub einen Stern