[{"data":1,"prerenderedAt":164},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Fdecisions\u002F001-custom-email-renderer":4,"surround-de-\u002Fdeveloper\u002Fdecisions\u002F001-custom-email-renderer":155},[],{"id":5,"title":6,"body":7,"description":147,"extension":148,"meta":149,"navigation":150,"path":151,"seo":152,"stem":153,"__hash__":154},"content_de\u002F3.developer\u002Fdecisions\u002F2.001-custom-email-renderer.md","ADR-001: Eigener E-Mail-Renderer statt MJML",{"type":8,"value":9,"toc":140},"minimark",[10,27,32,36,39,65,69,77,81,86,124,129],[11,12,13,21],"ul",{},[14,15,16,20],"li",{},[17,18,19],"strong",{},"Status:"," Angenommen",[14,22,23,26],{},[17,24,25],{},"Datum:"," 2024-06-15",[28,29,31],"h2",{"id":30},"kontext","Kontext",[33,34,35],"p",{},"Owlat muss eine JSON-Blockstruktur in responsive HTML-E-Mails überführen, die in allen großen E-Mail-Clients (Gmail, Outlook, Apple Mail, Yahoo) korrekt dargestellt werden. MJML ist der Industriestandard dafür und stellt eine Auszeichnungssprache bereit, die zu E-Mail-sicherem HTML kompiliert.",[33,37,38],{},"MJML hat für unseren Anwendungsfall allerdings Grenzen:",[11,40,41,47,53,59],{},[14,42,43,46],{},[17,44,45],{},"Keine feingranulare Kontrolle"," — MJML abstrahiert das zugrunde liegende tabellenbasierte HTML weg und erschwert damit fortgeschrittene Funktionen wie VML-Hintergründe, bedingte Inhalte oder clientspezifisches Rendering.",[14,48,49,52],{},[17,50,51],{},"Bundle-Größe"," — MJML ist eine große Abhängigkeit (~2 MB), die das Serverless-Backend aufblähen würde.",[14,54,55,58],{},[17,56,57],{},"Nicht passendes Blockmodell"," — Unser Editor verwendet ein JSON-Blockmodell (ähnlich Notion\u002FEditor.js). Blöcke in MJML-Markup zu konvertieren, nur damit MJML daraus HTML macht, fügt eine unnötige Übersetzungsschicht hinzu.",[14,60,61,64],{},[17,62,63],{},"Erweiterbarkeit"," — Eigene Blocktypen in MJML zu ergänzen erfordert MJML-Komponenten, die dessen interner API entsprechen; diese ist schlecht dokumentiert und eng an die Rendering-Pipeline gekoppelt.",[28,66,68],{"id":67},"entscheidung","Entscheidung",[33,70,71,72,76],{},"Einen eigenen tabellenbasierten HTML-E-Mail-Renderer (",[73,74,75],"code",{},"@owlat\u002Femail-renderer",") bauen, der unser JSON-Blockformat direkt in E-Mail-sicheres HTML überführt.",[28,78,80],{"id":79},"konsequenzen","Konsequenzen",[33,82,83],{},[17,84,85],{},"Ermöglicht:",[11,87,88,91,98,101,112,115,118,121],{},[14,89,90],{},"Direkte Kontrolle über jedes HTML-Attribut und damit VML-Unterstützung für Outlook (bulletproof Buttons, Hintergrundbilder, Verläufe)",[14,92,93,94,97],{},"Render-Simulation pro Client (Option ",[73,95,96],{},"targetClient",") für treffsichere Vorschauen",[14,99,100],{},"Eigene Block-Registry für Blocktypen von Drittanbietern",[14,102,103,104,107,108,111],{},"CSS-Inlining mit selektiven Annotationen (",[73,105,106],{},"@inline"," \u002F ",[73,109,110],{},"@head-only",")",[14,113,114],{},"Dark-Mode-Unterstützung mit Overrides pro Block",[14,116,117],{},"AMP-E-Mail-Ausgabe als erstklassiges Format",[14,119,120],{},"Analyse der E-Mail-Größe und Kompatibilitäts-Scoring",[14,122,123],{},"Kleineres Bundle — der Renderer wiegt ~50 KB gegenüber MJMLs ~2 MB",[33,125,126],{},[17,127,128],{},"Trade-offs:",[11,130,131,134,137],{},[14,132,133],{},"Wir tragen die volle Komplexität der Eigenheiten von E-Mail-Clients (Outlook-Conditional-Comments, CSS-Stripping in Gmail, Abstandsfehler bei Yahoo)",[14,135,136],{},"Neue Teammitglieder können sich nicht auf die MJML-Dokumentation stützen — sie müssen die API unseres Renderers lernen",[14,138,139],{},"Wir müssen eigene Kompatibilitätsdaten pflegen, statt uns auf die erprobte Ausgabe von MJML zu verlassen",{"title":141,"searchDepth":142,"depth":142,"links":143},"",2,[144,145,146],{"id":30,"depth":142,"text":31},{"id":67,"depth":142,"text":68},{"id":79,"depth":142,"text":80},"Warum Owlat einen eigenen tabellenbasierten HTML-E-Mail-Renderer gebaut hat, statt MJML zu verwenden, und damit volle Kontrolle über VML, Dark Mode und clientspezifisches Rendering gewinnt.","md",{},true,"\u002Fdeveloper\u002Fdecisions\u002F001-custom-email-renderer",{"title":6,"description":147},"3.developer\u002Fdecisions\u002F2.001-custom-email-renderer","KGvOT3mu9_JX1H-RQZOflZnbLvPSsYeCQoM_4Bs9RBs",[156,160],{"title":157,"path":158,"stem":159,"children":-1},"ADR-053: Sandboxed Plugin-Jobs","\u002Fdeveloper\u002Fdecisions\u002F053-sandboxed-plugin-jobs","3.developer\u002Fdecisions\u002F16.053-sandboxed-plugin-jobs",{"title":161,"path":162,"stem":163,"children":-1},"ADR-002: Convex als Backend","\u002Fdeveloper\u002Fdecisions\u002F002-convex-backend","3.developer\u002Fdecisions\u002F3.002-convex-backend",1786915110399]