pub-d1d7f5f57ea747fcb4c0d5bae0b1d227.r2.dev).
Sprache: 🇩🇪 Deutsch | 🇬🇧 English version
Dieser Artikel entstand direkt aus der Praxis – inklusive aller Debugging-Erkenntnisse, die wir erst durch echtes Ausprobieren herausgefunden haben.
Die Ausgangssituation
April 2026. Ziel: Eine moderne, KI-native Website fuer ein AI-Magazin. Die Wahl fiel auf EmDash, Cloudflares neues Open-Source-CMS als spirituellen Nachfolger von WordPress – serverless, sicher, KI-nativ. 75 Minuten, echter Stress, echte Loesungen. Dieser Artikel dokumentiert alles.
Die ehrliche Kostenrechnung
| Component / Komponente | $/Monat |
|---|---|
| Domain automatedweb.net (Cloudflare) | ~1 |
| Cloudflare Workers Paid Plan | 5 |
| R2, D1, SSL, CDN | 0 (inklusive / included) |
| Gesamt / Total | ~6 |
Monatliche Gesamtkosten: ~6 $ pro Monat. WordPress-Managed-Hosting: 15-50 $/Monat.
Schritt 1: Domain bei Cloudflare kaufen
Domain direkt bei Cloudflare registrieren – dann sind Domain und Workers-Hosting im selben Dashboard, keine DNS-Konfiguration noetig. .com war nur mit Bindestrich verfuegbar (automated-web.com) – ein No-Go. .net ist die sauberste Alternative.
Schritt 2: EmDash installieren
npm create emdash@latest
Setup-Wizard: Projektname → Cloudflare Workers (D1+R2) → Starter → npm. Ca. 2 Minuten.
⚠️ Fallstrick #1: Bestaetigung mit y erforderlich
npm fragt: Ok to proceed? (y). Nur Enter druecken → npm error canceled. Nochmal starten, y eingeben.
Schritt 3: Lokal testen
cd automatedweb && npm run dev
Admin unter http://localhost:4321/_emdash/admin. Site-Titel setzen, Passkey anlegen (kein Passwort!), Sample-Content aktivieren.
Schritt 4: Cloudflare vorbereiten
4a: R2 aktivieren
R2 einmalig im Cloudflare Dashboard aktivieren. Kreditkarte zur Verifikation noetig, die ersten 10 GB sind kostenlos.
⚠️ Fallstrick #2: worker_loader braucht den Paid Plan
Ohne Workers Paid Plan ($5/Monat) schlaegt der Deploy fehl:
binding LOADER of type worker_loader is invalid [code: 10021]
Kein Workaround. Paid Plan aktivieren, dann erneut deployen.
Schritt 5: Deployen
npm run deploy
Browser oeffnet sich fuer Cloudflare OAuth. Nach Login laeuft alles automatisch.
⚠️ Fallstrick #3: KV Namespace existiert bereits [code: 10014]
Wenn ein frueherer fehlgeschlagener Versuch Ressourcen angelegt hat:
a namespace with this account ID and title already exists [code: 10014]
Loesung: Cloudflare Dashboard → Workers & Pages → KV → Namespace my-emdash-site-session loeschen → erneut deployen.
⚠️ Fallstrick #4: wrangler.jsonc wird ignoriert
Die manuelle KV-ID in wrangler.jsonc hat keine Wirkung – npm run deploy nutzt intern --experimental-provision und ueberschreibt die Config. Einzige Loesung: Namespace loeschen, neu erstellen lassen.
Erfolgreicher Deploy:
🎉 All resources provisioned, continuing with deployment...
Deployed my-emdash-site triggers (6.41 sec)
https://my-emdash-site.yourname.workers.dev
Schritt 6: Custom Domain verbinden
Cloudflare Dashboard → Workers & Pages → Projekt → Settings → Custom Domains → Add. Sofort aktiv, keine Wartezeit.
⚠️ Fallstrick #5: Produktions-Datenbank ist leer
Das lokale Setup gilt nicht fuer die Live-Seite. Setup zweimal durchfuehren: lokal + live.
Schritt 7: KI-Integration via MCP
- Admin auf der Live-URL oeffnen (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 von der Live-URL erstellt werden
Das hat uns am meisten Zeit gekostet. Ein Token von localhost:4321 gilt nur lokal. Auf der Live-Seite kommt:
{"error":{"code":"INVALID_TOKEN","message":"Invalid or expired token"}}
Loesung: Token immer auf der eigenen Live-Domain erstellen.
⚠️ Fallstrick #7: Die richtige EmDash API-Struktur
Korrekter API-Pfad: /_emdash/api/content/posts (nicht /admin/posts)
Data-Wrapper erforderlich bei POST und PATCH:
// Falsch / Wrong - 400 VALIDATION_ERROR:
{ title: "Post", content: "..." }
// Richtig / Correct - 201:
{ data: { title: "Post", content: "..." } }
Ohne den Wrapper: 400 VALIDATION_ERROR – kein Hinweis auf den fehlenden Wrapper in der Fehlermeldung.
Unsere Empfehlungen
✅ Domain direkt bei Cloudflare kaufen – spart DNS-Konfiguration komplett
✅ Workers Paid Plan sofort aktivieren – ohne ihn laeuft EmDash nicht in Produktion
✅ R2 vor dem ersten Deploy aktivieren – sonst schlaegt Deploy fehl
✅ Bei KV-Fehlern: Namespace loeschen, neu deployen
✅ API-Token immer auf der Live-URL erstellen – nicht auf localhost
✅ data-Wrapper bei API-Calls nicht vergessen – { data: { ...fields } }
✅ Starter-Template waehlen – maximale Flexibilitaet
FAQ
Brauche ich Programmierkenntnisse?
Grundlegende Terminal-Kenntnisse reichen. Befehle kopieren und ausfuehren – echten Code schreiben nicht noetig.
Kann ich von WordPress zu EmDash migrieren?
EmDash unterstuetzt WordPress WXR-Exporte. Es gibt ein EmDash Exporter Plugin. Custom Post Types erfordern manuelle Nacharbeit.
Was passiert wenn meine Seite viral geht?
Workers Paid inkludiert 10 Mio. Requests/Monat, dann 0,30 $ pro weitere Million. Automatische Skalierung.
Warum gibt der MCP-Server 404 zurueck obwohl der Token stimmt?
Der API-Pfad ist falsch. Korrekt: /_emdash/api/content/posts. Ausserdem brauchen POST/PATCH den data-Wrapper.
Ist EmDash production-ready?
Seit April 2026 verfuegbar – fuer neue Projekte sehr gut geeignet. Fuer kritische Business-Websites noch 6-12 Monate warten.
Funktioniert EmDash fuer mehrsprachige Websites?
Noch keine eingebaute i18n. Unsere Loesung: Slugs mit Sprachkuerzel (artikelname-de / articlename-en) und Sprach-Tags.
Fazit
75 Minuten. 6 Dollar pro Monat. Eine moderne, KI-native, global gehostete Website mit MCP-Server, Passkey-Login und automatischer Skalierung – ohne eigenen Server. EmDash und Cloudflare Workers ist die ueberzeugendste Option fuer neue Projekte, die wir aktuell kennen.
Fallstrick 10: Media-Upload – R2, CSRF und der richtige Weg
Das hat uns am laengsten beschaeftigt. Bilder hochladen sollte einfach sein – ist es bei EmDash auf Cloudflare Workers aber nicht out-of-the-box.
Das Problem: NOT_SUPPORTED
Der POST /media/upload-url Endpoint gibt NOT_SUPPORTED zurueck:
{ "error": { "code": "NOT_SUPPORTED", "message": "Storage does not support signed upload URLs. Use direct upload." } }
Ursache: Das native R2-Binding (@emdash-cms/cloudflare) unterstuetzt keine Pre-Signed URLs – das ist ein Design-Entscheid von EmDash. Uploads muessen durch den Worker gehen.
Die Loesung: Drei Schritte
Schritt 1 – R2 Public Access aktivieren:
npx wrangler r2 bucket dev-url enable my-emdash-media
# → https://pub-XXXXX.r2.dev
Schritt 2 – publicUrl in astro.config.mjs eintragen:
storage: r2({ binding: "MEDIA", publicUrl: "https://pub-XXXXX.r2.dev" })
Schritt 3 – Rebuild + Deploy:
npm run build && npm run deploy
Der CSRF-Bypass fuer API-Uploads
Externe POST-Requests werden von Cloudflare mit 403 blockiert. Der korrekte Header laut EmDash-Quellcode (src/api/csrf.ts):
headers: {
"Authorization": "Bearer TOKEN",
"X-EmDash-Request": "1", // ← Das ist der Magic Header
...form.getHeaders()
}
Dieser Header signalisiert EmDash, dass es sich um einen legitimen internen Request handelt. Browser koennen ihn cross-origin nicht setzen – deshalb ist er sicher als CSRF-Schutz.
Fuer externe Scripts (z.B. vom lokalen PC)
Node.js-Skripte koennen den Header problemlos setzen. Wichtig: Den Request ohne Origin-Header senden – dann greift laut CSRF-Code die Server-to-Server-Ausnahme.
Dieser Fallstrick hat uns mehrere Stunden gekostet – weil die Fehlermeldung irreführend war und wir durch mehrere Schichten von Cloudflare WAF, EmDash CSRF und R2-Binding-Logik navigieren mussten.Dieser Artikel wurde von Claude direkt via MCP veroeffentlicht – nachdem wir gemeinsam alle Fallstricke debuggt hatten.