Die Ausgangssituation
April 2026. Mein Ziel: Eine moderne, schnelle, KI-native Website für ein Automatisierungsmagazin namens Automated Web – so günstig und wartungsarm wie möglich.
Die Wahl fiel auf EmDash, Cloudflares neues Open-Source-CMS, das am 1. April 2026 als spiritueller Nachfolger von WordPress gestartet ist. Was folgte: 75 Minuten produktiver Zusammenarbeit mit Claude, echte Fehler und API-Eigenheiten – und am Ende eine live Website für rund 6 Dollar pro Monat. Dieser Artikel dokumentiert alles.
Die ehrliche Kostenrechnung
| Komponente | Kosten/Monat | Anmerkungen |
|---|---|---|
| Domain automatedweb.net | ~1 $ | 11,86 $/Jahr bei Cloudflare |
| Workers Paid Plan | 5 $ | Pflicht – Free Plan reicht nicht |
| R2 Storage (bis 10 GB) | 0 $ | Kostenlos, aber Kreditkarte erforderlich |
| D1 Datenbank | 0 $ | Inklusive |
| SSL-Zertifikat | 0 $ | Automatisch |
| Globales CDN | 0 $ | Cloudflare-Netzwerk weltweit |
| Gesamt | ~6 $ | WordPress-Hosting: 15–50 $/Monat |
Schritt 1: Domain bei Cloudflare kaufen
Domain direkt beim Cloudflare Registrar registrieren – dann sind Domain und Workers-Hosting im selben Dashboard. Keine DNS-Konfiguration, keine Nameserver-Übertragung nötig.
Schritt 2: EmDash installieren
npm create emdash@latest
Der Setup-Wizard führt durch: Projektname → Cloudflare Workers (D1 + R2) → Starter-Template → npm. Etwa 2 Minuten insgesamt.
⚠️ Fallstrick #1: Bestätigung mit „y" ist Pflicht
npm fragt: „Ok to proceed? (y)". Enter ohne „y" einzutippen → npm error canceled.
Schritt 3: Lokal testen
cd automatedweb && npm run dev
Admin-Panel unter localhost:4321/_emdash/admin. Titel setzen, Passkey anlegen (kein Passwort!), Sample-Content aktivieren.
Schritt 4: Cloudflare vorbereiten
⚠️ Fallstrick #2: worker_loader braucht den Paid Plan – kein Workaround
X [ERROR] binding LOADER of type worker_loader is invalid [code: 10021]
Den Workers Paid Plan vor dem ersten Deploy aktivieren. Es gibt keinen kostenlosen Workaround.
Schritt 5: Deployen
npm run deploy
⚠️ Fallstrick #3: KV Namespace existiert bereits [code: 10014]
Lösung: Cloudflare Dashboard → Workers & Pages → KV → Namespace löschen → erneut deployen.
⚠️ Fallstrick #4: wrangler.jsonc wird beim Provisioning ignoriert
Namespace löschen und von Wrangler neu erstellen lassen.
Schritt 6: Custom Domain verbinden
Cloudflare Dashboard → Workers & Pages → Settings → Custom Domains → Add. Sofort aktiv.
⚠️ Fallstrick #5: Produktionsdatenbank ist leer – Setup zweimal durchführen
Lokale und Produktionsdatenbank sind vollständig getrennt. Setup zweimal durchführen: lokal und auf der Live-Seite.
Schritt 7: KI-Integration via MCP
- Admin auf der Live-URL öffnen (nicht localhost!)
- Settings → API Tokens → neuen Token erstellen
- Claude Desktop Config bearbeiten:
%APPDATA%\\Claude\\claude_desktop_config.json - EmDash als MCP-Server eintragen, Claude Desktop neu starten
⚠️ Fallstrick #6: Token muss auf der Live-URL erstellt werden
Ein Token von localhost:4321 funktioniert nur lokal. Auf der Live-Seite gibt es INVALID_TOKEN.
⚠️ Fallstrick #7: EmDash-API-Struktur weicht von REST-Konventionen ab
Korrekter Pfad: /_emdash/api/content/posts. Bei POST-Requests ist ein Data-Wrapper erforderlich:
// Richtig – 201 Created:
{ data: { title: "Post", content: "..." } }
// Falsch – 400 VALIDATION_ERROR:
{ title: "Post", content: "..." }
⚠️ Fallstrick #8: PATCH gibt 404 zurück – PUT verwenden
PUT für Updates, POST /:id/publish zum Veröffentlichen. Der Slug lässt sich nach dem Veröffentlichen nicht mehr ändern.
⚠️ Fallstrick #9: npm run deploy baut NICHT neu
Immer beide Befehle ausführen:
npm run build && npm run deploy
⚠️ Fallstrick #10: Media-Upload – R2, CSRF und der richtige Weg
Der Endpunkt POST /media/upload-url gibt NOT_SUPPORTED zurück. Dreistufige Lösung:
# 1. R2 Public Access aktivieren:
npx wrangler r2 bucket dev-url enable my-emdash-media
# 2. publicUrl in astro.config.mjs eintragen:
storage: r2({ binding: "MEDIA", publicUrl: "https://pub-XXXXX.r2.dev" })
# 3. Rebuild und Deploy:
npm run build && npm run deploy
Externe POST-Requests brauchen den CSRF-Bypass-Header:
headers: {
"Authorization": "Bearer TOKEN",
"X-EmDash-Request": "1",
...form.getHeaders()
}
⚠️ Fallstrick #11: Astros CSRF-Check blockiert multipart/form-data
Der 403-Fehler kommt von Astros Origin-Check in node_modules/astro/dist/core/app/middlewares.js – nicht von EmDash selbst.
// Nach: if (SAFE_METHODS.includes(request.method)) { return next(); }
const authHeader = request.headers.get("authorization") || "";
const isApiRoute = url.pathname.startsWith("/_emdash/api/");
if (isApiRoute && authHeader.startsWith("Bearer ec_pat_")) {
return next();
}
⚠️ Der Patch geht bei npm install verloren → mit dem MCP-Tool apply_astro_patch automatisch neu anwenden.
⚠️ Fallstrick #12: EmDash Pages speichern kein HTML – PortableText-Konvertierung
EmDash konvertiert jeden PUT-Request mit HTML automatisch in PortableText-Blöcke. Das HTML ist nach dem Speichern weg – das ist eine bewusste Designentscheidung, kein Bug.
Die Lösung: Ein statisches Astro-Template. Die Seite direkt in src/pages/ schreiben – volle HTML-Kontrolle, kein CMS-Overhead.
⚠️ Fallstrick #13: Post-Karten auf der Homepage verlinkten ins Nirgendwo
Bug 1 – post.id statt post.slug: post.id als URL verwendet (eine ULID wie 01KN7DX6...) → 404.
Bug 2 – EmDash <Image>-Komponente in Collections: Schlägt mit relativen Pfaden in Collection-Views fehl.
// Falsch:
<a href={`/posts/${post.id}`}>
<Image image={post.data.featured_image} />
// Richtig:
<a href={`/de/posts/${post.slug}`}>
<img src={post.data.featured_image.url} alt={post.data.featured_image.alt} />
Meine Empfehlungen
Nach allen dreizehn Fallstricken stechen einige Entscheidungen als besonders wichtig heraus.
Die Domain direkt bei Cloudflare zu registrieren spart jede DNS-Konfiguration und hält alles in einem Dashboard. Den Workers Paid Plan vor dem ersten Deploy zu aktivieren verhindert einen vermeidbaren Fehler – er ist Pflicht, es gibt keinen Workaround. Dasselbe gilt für R2: vor dem Deploy aktivieren, nicht danach.
Wenn etwas schiefläuft, sind die häufigsten Fixes einfacher als sie aussehen. KV-Fehler 10014 bedeutet: Namespace löschen und neu deployen. Ein 404 auf den API-Token kommt fast immer daher, dass er auf localhost statt auf der Live-URL erstellt wurde. Der Data-Wrapper bei POST-Requests – { data: { title, content } } statt flachem JSON – und PUT statt PATCH für Updates sind die zwei API-Muster, über die die meisten stolpern.
Für komplexe Seiten sind statische Astro-Templates in src/pages/ verlässlicher als CMS Pages und geben volle HTML-Kontrolle. In Card-Templates immer post.slug als URL-Parameter verwenden, nie post.id. Und bei Template-Änderungen gilt: erst npm run build, dann npm run deploy – nicht nur den Deploy-Befehl allein.
FAQ
Brauche ich Programmierkenntnisse?
Grundlegende Terminal-Kenntnisse reichen. Befehle kopieren und ausführen – echten Code schreiben ist nicht nötig.
Warum gibt der MCP-Server 404 zurück, obwohl der Token stimmt?
Falscher API-Pfad oder fehlender Data-Wrapper. Korrekter Pfad: /_emdash/api/content/posts.
Kann ich von WordPress migrieren?
EmDash unterstützt den WordPress WXR-Export-Import. Custom Post Types erfordern manuelle Arbeit.
Was, wenn meine Seite viral geht?
Der Workers Paid Plan enthält 10 Millionen Requests pro Monat, danach 0,30 $ pro Million. Skalierung erfolgt automatisch.
Ist EmDash produktionsreif?
Gestartet im April 2026 – ideal für neue Projekte. Für die Migration kritischer Business-Seiten sind weitere 6–12 Monate Reifung sinnvoll.
Fazit
75 Minuten. 6 Dollar pro Monat. Eine moderne, KI-native, global gehostete Website mit integriertem MCP-Server, Passkey-Authentifizierung und automatischer Skalierung – kein eigener Server nötig.
Dieser Artikel wurde von Claude direkt via MCP veröffentlicht – nachdem wir gemeinsam alle dreizehn Fallstricke debuggt hatten.
Über den Autor
Hendrik Muth
SEO- & KI-Enthusiast aus München. Ich experimentiere mit KI-Tools und Automatisierungs-Workflows – und baue Websites wie diese in unter 75 Minuten.
Weiteren Fallstrick entdeckt? Lass es mich wissen – ich aktualisiere diese Liste laufend.