Am 28. September 2026 wurde die Version 1.0 von EmDash offiziell veröffentlicht.
EmDash ist ein von Cloudflare entwickeltes, auf Astro basierendes Open-Source-CMS, das mit der Admin-Oberfläche direkt in die Astro-Website integriert ist und auf Cloudflare Workers + D1 + R2 läuft.
Es ist im Grunde die Astro-Version von WordPress.
In einem früheren Artikel haben wir unseren internen Blog "ゆるろぐ" von microCMS migriert. Da dieser seit Juni auf Version 0.22 steckengeblieben war, haben wir ihn diesen Mal auf die neueste Version 1.2.0 aktualisiert.
Die Höhepunkte von 1.0 sind Stabilität und sichere Upgrades, Plugins, die in einer Sandbox laufen, und MCP-Server für Agenten.
Zusammengefasst war die Migration in einem Tag abgeschlossen, aber es gab viele Fallstricke.
Wenn man leichtfertig davon ausgeht, dass es stabil sein sollte, weil es Version 1.0 ist, stößt man nicht bei der EmDash-Hauptkomponente selbst auf Probleme, sondern bei den umgebenden Abhängigkeiten.
Voraussetzung: 0.22 → 1.2 musste manuell erhöht werden
1.2 enthielt ein offizielles Upgrade-CLI namens upgrade-emdash.
Es aktualisiert die Abhängigkeiten und generiert eine standortspezifische UPGRADE.md, funktioniert aber nur ab Version 0.35, daher war es von 0.22 aus nicht nutzbar.
Zwischen 0.22 und 1.2 gibt es 47 Datenbankmigrationen, und einige davon sind ziemlich zerstörerische Änderungen.
Es war nicht mit npm install emdash@latest erledigt.
1. Erstelle eine Sicherung und repliziere die Produktions-DB lokal
npx wrangler d1 export <database-name> --remote --output=backups/pre-1.2.sql
Wir leiten dies an die lokale D1 weiter und führen eine Migration mit denselben Daten wie in der Produktion durch.
2. Abhängigkeiten aktualisieren
Paket | vor der Migration | Nach der Migration |
|---|---|---|
emdash / @emdash-cms/cloudflare / @emdash-cms/admin | 0.22.0 | 1.2.0 |
@emdash-cms/plugin-forms | 0.1.1 | 0.2.9 |
astro | 6.1.2 | 6.4.8 |
wrangler | 4.80 | 4.148 |
Wrangler musste aufgrund der Peer-Anforderung für emdash 1.2 (4.99 oder höher) aktualisiert werden. Daher habe ich die Übergangslösung aus der Version 0.22 ebenfalls entfernt. @astrojs/cloudflare erfüllte die Peer-Anforderungen bereits, daher habe ich es zu diesem Zeitpunkt bei Version 13.1.6 belassen. Dies wird die Ursache der nächsten Hürde sein.
- patch-package für OAuth-Route: ein Workaround für einen Fehler in Version 0.22, der im Hauptprojekt bereits behoben wurde
- CSS-Injection im Admin-Panel: In Version 0.22 verwendete das Admin-Panel CSS für die UI-Bibliothek kumo 2.4, aber die Lockdatei zog Version 2.6, wodurch die Schaltflächen zum Anmelden und Veröffentlichen mit „weißem Text auf transparentem Hintergrund" unsichtbar wurden. In Version 1.2 wurde dies auf Seite des Hauptprodukts behoben
3. dev startet nicht (Falle: miniflare-Versionsabweichung)
Das Problem beim Ausführen von npm run dev nach dem Update war eine Version-Abweichung bei miniflare.
Wrangler 4.148 verwendet miniflare 5 und aktualisiert die lokale D1-Tabelle (unter .wrangler/state/v3/) auf 3 Spalten.
Allerdings@astrojs/cloudflare 13.1.6 ist mit miniflare 4 gebündelt und kann die lokale Tabelle _cf_ALARM aufgrund der unterschiedlichen Spaltenzahl nicht lesen.
Die Abhilfe bestand auch darin, das bisher ausstehende @astrojs/cloudflare zu aktualisieren und die miniflare-Version an wrangler anzupassen. Merken Sie sich einfach: „Die miniflare-Versionen von wrangler und dem Adapter müssen übereinstimmen" – beim nächsten Mal geht es dann sofort.
In Version 0.22 wurde der emdash dev-Befehl entfernt, daher haben wir das dev-Skript auf astro dev zurückgestellt. Migration und Typengenerierung werden beim Start von astro dev ausgeführt.
4. Das Staging-Menü ist verschwunden (Falle: seed.json Menüs)
Nach dem Starten von dev, dem Durchlaufen von 90 Migrationen und dem Upload zu Staging öffnete ich das Admin-Panel und stellte fest, dass das globale Navigationsmenü auf Japanisch leer war.
Das Problem liegt in den menus und widgetAreas in seed/seed.json.
Das Seeding-Verfahren von EmDash löscht alle Einträge und erstellt sie leer neu, wenn ein Menü oder Widget-Bereich mit demselben Namen vorhanden ist. Dabei werden alle Elemente gelöscht und dann leer neu erstellt.
In seed.json blieb als Vorlage eine Menü-Definition mit \"items\": [] erhalten, weshalb das Menü bei jedem Seeding-Lauf zurückgesetzt wurde.
Die Lösung bestand darin, die Schlüssel menus und widgetAreas vollständig zu löschen.
Der Menüinhalt wird im Admin-Panel verwaltet, daher gibt es keinen Grund, ihn in seed zu speichern.
5. Der Link zum englischen Artikel wird zu /en/posts/en/slug (Falle: Gebietsschema-Präfix in entry.id)
Dies ist eine Spezifikationsänderung in Version 1.2.
Bei mehrsprachigen Websites erhält getEmDashCollection() nun ein Gebietsschema-Präfix in der zurückgegebenen entry.id. Für einen englischen Artikel wäre das en/my-post.
Yururog hat Artikel-URLs aus entry.id zusammengestellt, daher wurden die Links zu englischsprachigen Artikeln doppelt als /en/posts/en/my-post.
In der Übersicht, den Hervorgehobenen Artikeln, Suchergebnissen, RSS und kanonischen URLs – überall, wo URLs zusammengestellt werden – ersetze ich alles durch entry.data.slug.
Da der Typ von entry.data.slug string | null ist, muss ich auch den Typ auf der Empfängerseite anpassen.
Es hilft, sich zu merken, dass entry.id der Schlüssel ist, entry.data.slug die URL und entry.data.id die Datenbank-ULID (für API-Aufrufe) ist.
6. Jede Minute tritt ein Fehler auf (Falle: Cron Trigger und Worker-Eintrag)
In 1.x werden geplante Beiträge und regelmäßige Plugin-Verarbeitung durch den scheduled() Handler des Workers ausgelöst.
Da Cloudflare über keinen internen Timer verfügt, gibt es keinen Cron Trigger, und geplante Beiträge werden nicht zur geplanten Zeit veröffentlicht.
Daher habe ich einen Cron Trigger in wrangler.jsonc hinzugefügt.
"triggers": { "crons": ["* * * * *"] }Dann erhalten Sie jede Minute die Fehlermeldung "Handler does not export a scheduled() function".
Das liegt daran, dass der Worker-Eintrag scheduled() nicht exportiert.
Die Lösung besteht darin, src/worker.ts durch den offiziellen Eintrag zu ersetzen.
export { default, PluginBridge } from "@emdash-cms/cloudflare/worker";Damit verfügen Sie neben fetch und scheduled auch über PluginBridge für Sandbox-Plugins.
Ich habe es selbst ausprobiert
Das Gute am Update auf 1.2.
- Der Editor wurde überarbeitet und ist benutzerfreundlicher. Das Slash-Menü ist gruppiert, und die Symbolleiste folgt dem Cursor. Es funktioniert auch auf Mobilgeräten.
- Der Video-Block ist jetzt im Standard enthalten. Ich habe Video-Einbettungen bisher mit benutzerdefinierten Plugins realisiert und möchte diese später ersetzen.
- Alle provisorischen Maßnahmen aus der Version 0.22 konnten entfernt werden. Keine patch-package oder CSS-Injektionen mehr nötig.
Punkte, die zu beachten sind.
- Von 1.0 zu 1.2 in 10 Tagen – schnelle Entwicklung. In absehbarer Zeit wird eine Überprüfung in der Staging-Umgebung bei jedem Minor-Update erforderlich sein.
Fazit
- 0.22 → 1.2 ist eine manuelle Migration.
Das upgrade-emdashCLI-Tool ist nur ab Version 0.35 verfügbar. - wrangler- und Adapter-miniflare-Generationen abstimmen → ohne Abstimmung startet dev nicht
- „seed.json" enthält keine leeren Vorlagen für
menus/widgetAreas→ werden bei jedem Seed gelöscht - Mehrsprachige Websites haben ein Gebietsschema-Präfix bei
entry.id→ die URL kommt vonentry.data.slug - Um einen Cron Trigger hinzuzufügen, muss das Worker-Eintrag auf
@emdash-cms/cloudflare/workergesetzt werden
Während jede dieser Änderungen nur wenige Zeilen Code erfordert, kostet das schrittweise Nachschlagen und Beheben überraschend viel Zeit.
Dennoch ist die Tatsache, dass wir bei Version 0.22 angewendete Patches und CSS-Behelfslösungen vollständig entfernen konnten, ein Beweis dafür, dass kleine Bugs bis zur offiziellen Veröffentlichung behoben werden.
Vor einem halben Jahr war es noch ein experimenteller Ansatz, aber nach Version 1.0 ist das CMS, wenn man die Aufwände für die regelmäßigen Aktualisierungen miteinkalkuliert, zu einer echten Option für den produktiven Einsatz geworden.
Von DTP in die Web-Welt – und dann Markup, Frontend, Projektleitung und Accessibility alles gemeistert: ein "Technik-Weise". Seit den Anfangstagen von Liberogic vielseitig tätig und mittlerweile eine lebende Wissensquelle im Unternehmen. Derzeit fasziniert von der Frage "Können wir Accessibility-Umsetzung noch stärker mit KI unterstützen?" und erforscht Optimierungsmöglichkeiten durch gezieltes Prompt-Engineering. Technisch wie gedanklich immer noch in Entwicklung.
Ayumi Futamata
IAAP-zertifizierter Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director