Es gibt viele Gründe, warum ich Hugo liebe: keine Datenbank, keine Sicherheitslücken, keine aufgeblähte Admin-Oberfläche. Stattdessen habe ich pfeilschnelle Ladezeiten, volle Kontrolle über mein Layout und Markdown-Dateien, die ich im Editor meiner Wahl schreibe.

Aber – und das weiß jede:r, der schon länger mit Hugo arbeitet – der Verzicht auf ein CMS bedeutet auch: Du bist selbst für Konsistenz zuständig. Kategorien, Tags, Front Matter, Shortcodes … all das will sauber gepflegt werden. Und wer schon einmal im Nachhinein Dutzende Beiträge harmonisieren musste, weiß: Das ist kein Spaß.

Mein Problem mit der Syntax-Disziplin

In WordPress klickst du dich einfach durch die Maske, wählst Kategorien aus, setzt ein paar Schlagwörter und speicherst. In Hugo gibt es kein „Pflichtfeld“ – wenn du categories mal als Liste schreibst, mal als Inline-Array, merkt es niemand.
Das Ergebnis: ein bunter Zoo aus Schreibweisen, uneinheitlichen Tags und mal funktionierenden, mal fehlerhaften Shortcodes.

Die Lösung

Ich habe mir mit ChatGPT5 einen Mini-Editor als Ein-Datei-App gebaut: Doppelklick, läuft lokal im Browser. Schreiben wie in WordPress, veröffentlichen wie in Hugo.

Mein Editor in 60 Sekunden

  • Single-File-App: reines HTML + Vanilla JS + TailwindCDN. Keine Installation, kein Build, keine Abhängigkeiten.
  • Toolbar & Shortcuts: Bold, Italic, Headings, Listen, Zitat, Code, Link, HR – plus Figure- und Video-Shortcode auf Knopfdruck.
  • Kategorien & Tags als Chips: Auswahl aus Presets, Duplikate werden vermieden.
  • Inline-Dateinamen → Shortcodes: Eine Zeile nur mit foto.webp oder clip.mp4? Wird beim Export automatisch ins figure-Markdown erweitert. Magic!
  • Front-Matter-Generator: Titel, Datum, Slug, Description, Cover – alles sauber formatiert.
  • Export: Ein Klick → index.md wird lokal gespeichert
  • Nichts verlässt den Rechner: Auto-Save in localStorage, sonst offline
Alt
So sieht der Post-Editor aus: One Pahge - One Love

WYSIWYG-Feeling ohne Ballast

Oben sitzt eine kompakte Toolbar (mit zugänglichen Tooltips/ARIA), darunter ein großer Textbereich.
Die Buttons machen genau das, was man erwartet – Undo-freundlich und positionsgenau:

  • Überschriften (H1–H3): setzt oder ersetzt führende # am aktuellen Zeilenanfang
  • Fett/Kursiv: markierte Auswahl wird mit **…** bzw. _…_ eingerahmt
  • Zitat & Trennlinie: > als Zeilenpräfix bzw. --- einfügen
  • Listen: ungeordnet (- ) und nummeriert (1. 2. 3.), vorhandene Nummern werden sauber neu berechnet
  • Links: kommen direkt aus der Toolbar
  • Code: inline oder als Block (drei Backticks)
  • Medien-Shortcodes: kommen direkt aus der Toolbar
  • Keyboard-Shortcuts: Von Strg/⌘+B (Fett) bis Alt+Umschalt+V (Video) ist alles drin – auch Headings mit Strg/⌘+Alt+1/2/3

Weil ich ein kleiner Nerd bin, was doppelte Leerzeichen und Leerzeichen an Satzenden angeht, habe ich einen Live-Checker eingebunden, der mich darauf hinweis, an welchen Stellen sich Leerzeichen oder zu viele Zeichen reingeschumelt haben. Der Warnsystem im Editor prüft: Fehlt cover.image? Fehlen Alt-Texte? Ist description länger als 160 Zeichen? Der Markdown-Lintingzeigt doppelte Leerzeilen, falsche Überschriftenhierarchien und zu lange Zeilen an.

Alt
Dem entgeht nichts

Unter der Haube sorgt die Editor-Logik mit setRangeText() (Fallback auf execCommand) für sauberes Einfügen und korrektes Auswählen – sprich: Undo/Redo bleibt nativ und stabil.

Kategorien & Tags: konsistent by design

Oben wählst du eine Kategorie (mit „Neue“ erweiterbar), unten baust du Tags als Chips.
Kein Duplikat, kein Trim-Chaos. Beim Export werden beide Taxonomien als Inline-Arrays geschrieben – z.B.:

  • categories: ["Technik"]
  • tags: ["Hugo", "Markdown", "Produktivität"]

Shortcode-Magie aus dem Fließtext

Mein Lieblingsfeature: Inline-Dateinamen im Text werden automatisch erkannt und beim Export in Shortcodes verwandelt:

Heißt: Du legst Medien in images/ und notierst beim Schreiben nur meinbild.webp.
Der Konverter erledigt den Rest (convertInlineMedia() prüft Endungen, extrahiert Basenames und setzt das global eingestellte preload).

Front Matter: einmal klicken, alles sitzt

Der Export-Button baut dir ein perfektes Front Matter zusammen:

  • title, date (ISO, via Datepicker/„Heute“), slug (automatisch aus Titel oder manuell), description
  • categories + tags als Inline-Arrays
  • cover.image mit images/<datei>, cover.alt, cover.relative: true
  • Flags wie draft: true und ShowToc: true

Sonderfälle fängt der Generator ab:

  • YAML-Escape von Anführungszeichen und Backslashes (yamlEscape())
  • Sauberer Slug via toSlug() (Diakritika entfernt, nur [a-z0-9-], Trim von Bindestrichen)

Qualität, die man spürt: Auto-Save & Restore

Nichts ist schlimmer als verlorener Text. Der Editor speichert alles automatisch (inkl. Dark-Mode-Wahl) in localStorage unter mk_hugo_editor_state_v1 und stellt beim Öffnen den gesamten Zustand wieder her – Undo-freundlich und ohne dich zu nerven.

Technik für Neugierige 🛠️

  • Stack: Tailwind via CDN, Dark-Mode per class + prefers-color-scheme, State im localStorage
  • Dark-Toggle: speichert mk_theme und respektiert das OS-Theme
  • Toolbar-Engine:
    • wrapSelection(prefix, suffix) für Inline-Formatierungen
    • toggleLinePrefix(prefix) für Zitate/UL
    • makeOrderedList() nummeriert neu und entfernt alte Präfixe
    • applyHeading(level) setzt Hashes zeilensicher
    • insertLink() positioniert Cursor direkt in die URL
  • Medien-Konverter: convertInlineMedia(text, videoPreload) arbeitet zeilenbasiert mit Regex-Filtern, akzeptiert auch ./images/… oder images/…
  • Export: per Blob + URL.createObjectURLindex.md
  • Barrierefreiheit: Fokus-Styles (:focus-visible), klare Button-Kontraste, Toolbar mit role="toolbar" und Gruppierungen

Roadmap (Ideen, Feedback welcome) 🧭

  • Live-Preview mit Sanitizing
  • Konfigurierbare Shortcode-Maps (eigene Shortcodes)
  • Optional: Zielordner-Auswahl content/post/YYYY/slug/ beim Export

Dein Turn 🔧

Et voila: hier findest du meinen Hugo Post-Editor. Lass mich bitte wissen, wie du ihn findest, was dir fehlt, ob ich etwas optimieren soll. Sharing is Caring! <3