Mail-Templates
zvv-mailer rawHtml-Pattern. Der Mailer wrapt automatisch mit ZVV-Header + Footer — die App liefert nur Body-Content (Paragraphen + Buttons). Demo-Slugs sind fiktiv (atlas-demo/*) — kein echter Send.
Wire-Payload
atlas-demo/welcomeWillkommen bei ZVV Atlas
POST /api/newsletters/<slug>/sendjson
{
"subject": "Willkommen bei ZVV Atlas",
"rawHtml": "<p>Hallo Marcel,</p>\n<p>willkommen bei der ZVV Atlas Foundation. Du findest die Specs auf <a href=\"https://zvvch.github.io/zvv-atlas\">zvvch.github.io/zvv-atlas</a> und Live-Examples auf <a href=\"https://atlas.zvv.dev\">atlas.zvv.dev</a>.</p>\n<p style=\"margin:24px 0\">\n <a href=\"https://atlas.zvv.dev\" style=\"display:inline-block;background:#0072CE;color:#fff;text-decoration:none;padding:10px 22px;border-radius:6px;font-weight:600\">Showcase öffnen</a>\n</p>\n<p style=\"font-size:13px;color:#6b7280\">Bei Fragen melde dich gerne — ict@zvv.zh.ch.</p>",
"externalRef": "atlas-demo/welcome:demo:fixed-001",
"headerTitle": "Willkommen",
"recipients": [
"demo@example.ch"
]
}Live-Preview (Iframe-Sandbox)
From: ict@zvv.zh.ch · Subject: Willkommen bei ZVV Atlas
Atlas Mailer-Pattern
Jede ZVV-App nutzt zvv-mailer als gemeinsamen Sende-Service. Slug-Mapping regelt Sender-Email + Default-Audience pro App.
mailer-client Aufruftsx
// lib/notifications/mailer-client.ts
await sendNewsletter({
subject: 'Anmelde-Link für die ZVV App',
message: bodyHtml, // ← rawHtml: nur Body-Content, kein <html>
headerTitle: 'Anmeldung', // ← wird vom Mailer-Template als H1 gerendert
externalRef: 'app:magic-link:' + Date.now(),
recipients: [{ email: user.email }],
})⚠️ Bekannte Falle: RAW_HTML_WRAPPED_BY_NON_RAW_TEMPLATE
Wenn der Slug gegen ein Non-Raw-Template gemappt ist, strippt der Mailer den Body silent → leere „Newsletter"-Card im Postfach. Fix in der Mailer-Slug-Settings (Template auf zvv-raw).