# MJML-Editoren und API

> Erstellen Sie responsive Vorlagen und Kampagnen mit MJML, einer Alpha, die nur dem Emailit-Team offensteht. Visual Editor und Code Editor, gespeicherte Dokumente, Validierung, Temple in MJML, Zusammenarbeit in Echtzeit und die MJML-API.

[MJML](https://mjml.io) ist eine Auszeichnungssprache für responsive E-Mails. Sie schreiben Abschnitte, Spalten und Komponenten wie `<mj-text>` und `<mj-button>`, und MJML kompiliert sie zu HTML, das in allen E-Mail-Clients einheitlich dargestellt wird. In Emailit kann MJML die Quelle einer Vorlage oder Kampagne sein: Sie schreiben es in den Editoren der Weboberfläche oder senden es per API, und Emailit validiert es und kompiliert das HTML.

> **MJML ist in der Alpha:** MJML ist in der Alpha und steht nur dem Emailit-Team offen, solange wir es testen. Workspaces von Kunden sehen die MJML-Editoren noch nicht, und API-Anfragen, die MJML-Vorlagen erstellen oder ändern oder die MJML-Endpunkte aufrufen, geben `403` mit `error: "mjml_alpha"` zurück. Diese Seite beschreibt, wie MJML funktioniert, damit Sie es einplanen können. Mit MJML erstellte Vorlagen und Kampagnen lassen sich weiterhin von allen versenden.

## Übersicht

- **Vorlagen**: `editor: "mjml"` mit dem MJML in `source`. Siehe [Vorlage erstellen](/de/docs/api-reference/templates/create/).
- **Kampagnen**: `content_type: "mjml"` mit dem MJML in `content`. Siehe [Kampagnen](#campaigns).
- **Automatisierungen**: Der Schritt **Send email** sendet eine MJML-Vorlage wie jede andere Vorlage. Siehe [Automatisierungen](#automations).
- **MJML-Endpunkte**: [MJML validieren](/de/docs/api-reference/mjml/validate/), [MJML rendern](/de/docs/api-reference/mjml/render/) und [MJML-Referenz abrufen](/de/docs/api-reference/mjml/reference/).

### Wer MJML nutzen kann

Während der Alpha steht MJML nur den Plattform-Admins von Emailit zur Verfügung. Die Rolle **Admin** in einem Workspace reicht nicht aus.

| Wo | Emailit-Team | Alle anderen |
| --- | --- | --- |
| Weboberfläche | MJML-Editoren, MJML-Import, **Edit with AI** und Zusammenarbeit in Echtzeit | Keine MJML-Editoren. Eine MJML-Vorlage oder -Kampagne zeigt einen Hinweis, lässt sich in keinem Editor öffnen und wird trotzdem gesendet. |
| API | MJML-Vorlagen, MJML-Kampagnen und die MJML-Endpunkte | `403` mit `error: "mjml_alpha"`. `content_type: "mjml"` bleibt bei einer Kampagne eine reine Bezeichnung, wie vor der Alpha. Siehe [Kampagnen](#campaigns). |
| API-Schlüssel | Keine. API-Schlüssel gehören zu einem Workspace, nicht zu einer Person. | `403` mit `error: "mjml_alpha"` |
| MCP-Server | Die MJML-Tools und die MJML-Parameter der Tools für Vorlagen und Kampagnen | Nicht aufgeführt |

Alle können MJML-Vorlagen und -Kampagnen weiterhin umbenennen, veröffentlichen, exportieren, senden und löschen. Das Duplizieren einer MJML-Vorlage erstellt eine neue MJML-Vorlage und erfordert daher MJML-Zugriff.

### MJML-Version

Emailit kompiliert jedes MJML mit **MJML 5.4.1**, sowohl auf dem Server als auch in der Live-Vorschau der Editoren. Die Validierung prüft Tags, Attribute und Attributwerte gegen diese Version. [MJML-Referenz abrufen](/de/docs/api-reference/mjml/reference/) gibt die Version und alle Komponenten und Attribute zurück, die sie unterstützt.

### Editoren

Die Weboberfläche hat zwei MJML-Editoren. Beide sind versioniert und befinden sich als Version `0.x` in der Alpha.

| Editor | ID | Version | Beschreibung |
| --- | --- | --- | --- |
| MJML Visual Editor | `mjml-visual` | 0.2.0 (Alpha) | Drag-and-drop auf der gerenderten E-Mail, für alle MJML-Komponenten und -Attribute |
| MJML Code Editor | `mjml-code` | 0.2.0 (Alpha) | MJML mit Autovervollständigung, Inline-Validierung und einer Live-Vorschau für Desktop und Mobilgeräte |

Beide Editoren speichern eine Vorlage mit `editor: "mjml"`. Das gespeicherte Dokument hält fest, welcher Editor es zuletzt gespeichert hat und in welcher Version. Teammitglieder können dieselbe Vorlage oder Kampagne gleichzeitig bearbeiten. Siehe [Gemeinsam bearbeiten](#editing-together).

## Quellformate

Überall, wo Emailit MJML annimmt (das Feld `source` einer Vorlage, das Feld `content` einer Kampagne und das Feld `source` der MJML-Endpunkte), können Sie jedes dieser Formate senden:

| Format | Beispiel |
| --- | --- |
| MJML-Markup | Ein String, der mit `<mjml>` beginnt. Eine XML-Deklaration oder vorangestellte Kommentare sind erlaubt. |
| MJML-JSON | Das eigene JSON-Format von MJML, als Objekt oder JSON-String: `{ "tagName": "mjml", "attributes": {}, "children": [ … ] }`. Ending-Tags wie `mj-text` tragen ihr HTML in `content`. |
| Emailit-MJML-Dokument | Die Hülle, die Emailit speichert (siehe unten), als Objekt oder JSON-String |

Alles andere wird mit `document.unrecognized` abgelehnt. Quellen über 2 MB werden mit `document.too-large` abgelehnt.

### Das gespeicherte Dokument

Emailit speichert MJML in einer versionierten Hülle. Sie ist das `source` der Vorlage und der `content` der Kampagne:

```json
{
  "kind": "emailit/mjml",
  "schema_version": 1,
  "mjml_version": "5.4.1",
  "editor": "api",
  "editor_version": null,
  "format": "markup",
  "content": "<mjml>\n  <mj-body>\n    …\n  </mj-body>\n</mjml>"
}
```

| Feld | Beschreibung |
| --- | --- |
| `kind` | Immer `emailit/mjml`. |
| `schema_version` | Version des Aufbaus der Hülle. Derzeit `1`. |
| `mjml_version` | Das MJML-Release, auf das der Inhalt ausgelegt ist. Emailit setzt es auf die Version, mit der kompiliert wurde. |
| `editor` | Was das Dokument zuletzt geschrieben hat: `mjml-visual`, `mjml-code`, `ai` (**Edit with AI**) oder `api` (die API, die MCP-Tools und Datei-Importe). |
| `editor_version` | Version dieses Editors oder `null`. |
| `format` | `markup`: `content` ist MJML-Markup, so gespeichert, wie es geschrieben wurde, einschließlich Kommentaren und Formatierung. `json`: `content` ist MJML-JSON. |
| `content` | Das MJML. |

Was Sie senden, bestimmt das Format: Markup wird als `markup` gespeichert, MJML-JSON als `json`. Beides wird mit `editor: "api"` erfasst. Eine Hülle, die Sie senden, behält ihren `editor` und ihre `editor_version`.

API-Antworten geben `source` als diese Hülle zurück, serialisiert als JSON-String, und Sie können sie unverändert zurücksenden. Antworten enthalten außerdem ein Objekt `mjml` mit den Versionen der Hülle:

```json
"mjml": {
  "mjml_version": "5.4.1",
  "schema_version": 1,
  "editor": "api",
  "editor_version": null,
  "format": "markup"
}
```

Die Weboberfläche öffnet ein Dokument in dem Editor, der es zuletzt gespeichert hat. Per API geschriebene Dokumente öffnen sich im Code Editor, wenn `format` den Wert `markup` hat, und im Visual Editor, wenn es `json` ist.

## Kompilieren und speichern

Bei MJML-Vorlagen und -Kampagnen ist Emailit für das HTML zuständig:

- Beim Erstellen und Aktualisieren validiert Emailit das MJML und kompiliert es. Das kompilierte HTML wird als `html` der Vorlage gespeichert, und ein übergebenes `html` wird ignoriert.
- Der Versand verwendet das gespeicherte HTML. Temple-Tags bleiben darin erhalten und werden beim Senden für jeden Empfänger gerendert.
- Wenn Sie nur andere Felder aktualisieren, etwa `name` oder `subject`, wird nicht neu kompiliert.
- `text` wird nicht aus dem MJML erzeugt. Senden Sie `text` selbst, wenn Sie einen Nur-Text-Teil möchten.
- Wenn Sie eine bestehende Vorlage ohne `source` auf `editor: "mjml"` umstellen, wird das gespeicherte `source` der Vorlage kompiliert, das dann MJML sein muss.

Das HTML wird beim Speichern kompiliert. Das HTML einer bestehenden Vorlage ändert sich also erst, wenn sie erneut gespeichert wird.

```bash
curl https://api.emailit.com/v2/templates \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Welcome",
    "alias": "welcome",
    "subject": "Welcome, {{first_name|\"there\"}}",
    "editor": "mjml",
    "source": "<mjml><mj-head><mj-title>Welcome</mj-title><mj-preview>Your account is ready</mj-preview></mj-head><mj-body><mj-section><mj-column><mj-text>Hi {{first_name|\"there\"}}, welcome aboard.</mj-text><mj-button href=\"{{activation_url}}\">Activate account</mj-button></mj-column></mj-section></mj-body></mjml>"
  }'
```

Senden Sie sie dann wie jede andere Vorlage mit [E-Mail senden](/de/docs/api-reference/emails/send/): `"template": "welcome"` und ein Objekt `variables`.

## Validierung

Jedes Speichern führt dieselben Prüfungen aus wie [MJML validieren](/de/docs/api-reference/mjml/validate/):

- XML-Syntax: nicht geschlossene oder nicht zusammenpassende Tags und fehlerhafte Attribute (`xml.*`)
- MJML-Struktur, Attribute und Attributwerte für MJML 5.4.1 (`mjml.*`)
- Temple-Syntax und ausgeglichene `{{#if}}`-Blöcke (`temple.*`)
- Das Quellformat und die Versionen (`document.*`) sowie der Compiler selbst (`compiler.*`)

Jeder Befund ist eine Diagnose mit einem Schweregrad:

| Schweregrad | Auswirkung |
| --- | --- |
| `error` | Das MJML wird abgelehnt. Vorlagen und Kampagnen werden nicht gespeichert. |
| `warning` | Wird gespeichert. Wahrscheinlich ein Versehen: kein `<mj-title>`, Text außerhalb einer Komponente, ein Bedingungsblock, der über Komponentengrenzen reicht, oder HTML über der Kürzungsgrenze von Gmail bei 102 KB. |
| `info` | Wird gespeichert. Ein Vorschlag oder Hinweis: kein `<mj-preview>`, ein Bild ohne `alt` oder ein Dokument, das für eine ältere MJML-Version geschrieben wurde. |

Eine Diagnose hat diese Felder. Felder, die nicht zutreffen, werden weggelassen.

| Feld | Beschreibung |
| --- | --- |
| `severity` | `error`, `warning` oder `info` |
| `code` | Ein stabiler, maschinenlesbarer Code, zum Beispiel `mjml.invalid-child` |
| `message` | Eine verständliche Erklärung, oft mit einer Lösung („Did you mean color?“) |
| `line`, `column` | Position im Markup, ab 1 gezählt. Nur bei Markup-Quellen. |
| `tag` | Das Element, auf das sich die Diagnose bezieht |
| `attribute` | Das Attribut, falls es eines gibt |
| `path` | Pfad aus Kindindizes ab der Wurzel `<mjml>`. `[0, 1]` ist das zweite Kind des ersten Kinds. |

### Fehlerantwort

Wird eine Vorlage oder Kampagne mit Fehlerdiagnosen gespeichert, lautet die Antwort `422`. Für diese Quelle:

```xml
<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text colour="#333333">Hi {{first_name|"there"}}</mj-text>
        <mj-button href="{{cta_url}}">{{#if trial}}Start trial</mj-button>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>
```

lautet die Antwort:

```json
{
  "message": "The MJML is not valid.",
  "errors": {
    "source": [
      "Line 5: <mj-text> has no attribute colour. Did you mean color?",
      "Line 6: {{#if trial}} is never closed with {{/if}}."
    ]
  },
  "diagnostics": [
    {
      "severity": "error",
      "code": "mjml.unknown-attribute",
      "message": "<mj-text> has no attribute colour. Did you mean color?",
      "line": 5,
      "column": 18,
      "tag": "mj-text",
      "attribute": "colour",
      "path": [0, 0, 0, 0]
    },
    {
      "severity": "warning",
      "code": "mjml.missing-title",
      "message": "Add an <mj-title> to <mj-head>; clients and screen readers use it.",
      "line": 1,
      "column": 2,
      "tag": "mjml",
      "path": []
    },
    {
      "severity": "info",
      "code": "mjml.missing-preview",
      "message": "Add an <mj-preview> to control the inbox preview text.",
      "line": 1,
      "column": 2,
      "tag": "mjml",
      "path": []
    },
    {
      "severity": "error",
      "code": "temple.unclosed-if",
      "message": "{{#if trial}} is never closed with {{/if}}.",
      "line": 6,
      "column": 39,
      "tag": "mj-button",
      "path": [0, 0, 0, 1]
    }
  ]
}
```

- `errors.source` (`errors.content` bei Kampagnen) listet bis zu fünf Fehlermeldungen auf, mit ihrer Zeile, wenn sie bekannt ist.
- `diagnostics` listet alle Diagnosen auf, auch Warnungen und Infos.
- Eine fehlende oder leere Quelle gibt `422` mit `"message": "Validation failed"`, `"errors": { "source": ["The source field is required for MJML."] }` und einem leeren Array `diagnostics` zurück.

[MJML validieren](/de/docs/api-reference/mjml/validate/) führt dieselben Prüfungen ohne Speichern aus und gibt statt `422` den Status `200` mit `valid: false` zurück.

### Diagnosecodes

**XML** (Markup-Quellen)

| Code | Schweregrad | Bedeutung |
| --- | --- | --- |
| `xml.unclosed-tag` | error | Ein Element wird nie geschlossen. |
| `xml.unexpected-closing-tag` | error | Ein schließendes Tag passt zu keinem offenen Element. |
| `xml.malformed-closing-tag` | error | Ein schließendes Tag lässt sich nicht lesen. |
| `xml.unterminated-tag` | error | Einem öffnenden Tag fehlt das schließende `>`. |
| `xml.unterminated-attribute` | error | Einem Attributwert fehlt das schließende Anführungszeichen. |
| `xml.missing-attribute-value` | error | `name=` hat keinen Wert. |
| `xml.invalid-attribute` | error | Ein unerwartetes Zeichen innerhalb eines Tags. |
| `xml.duplicate-attribute` | error | Dasselbe Attribut zweimal an einem Element. Das erste wird verwendet. |
| `xml.unterminated-comment` | error | Einem Kommentar fehlt `-->`. |
| `xml.unterminated-cdata` | error | Einem CDATA-Abschnitt fehlt `]]>`. |
| `xml.unexpected-character` | error | Ein einzelnes `<` außerhalb eines Ending-Tags. |
| `xml.multiple-roots` | error | Mehr als ein Wurzelelement. |
| `xml.text-outside-root` | error | Text außerhalb von `<mjml>`. |
| `mjml.missing-root` | error | Das Dokument ist leer. |
| `xml.unquoted-attribute` | warning | Ein Attributwert ohne Anführungszeichen. |
| `xml.stray-text` | warning | Text zwischen Elementen, außerhalb jeder Inhaltskomponente. MJML ignoriert ihn. |
| `xml.unexpected-declaration` | warning | Eine Deklaration, nachdem `<mjml>` begonnen hat. |

**MJML**

| Code | Schweregrad | Bedeutung |
| --- | --- | --- |
| `mjml.unknown-tag` | error | Kein Element von MJML 5.4.1, mit einem „did you mean“-Vorschlag, wenn es ein ähnliches gibt. |
| `mjml.unknown-attribute` | error | Das Element hat kein solches Attribut. Bei `<mjml>` selbst eine Warnung. |
| `mjml.invalid-attribute-value` | error | Die falsche Art von Wert: keine Farbe, keine Einheit oder kein erlaubter Wert. |
| `mjml.invalid-child` | error | Das Element ist in seinem Elternelement nicht erlaubt. |
| `mjml.invalid-root` | error | Das Wurzelelement ist nicht `<mjml>`. |
| `mjml.missing-body` | error | Kein `<mj-body>`. |
| `mjml.duplicate-body` | error | Mehr als ein `<mj-body>`. |
| `mjml.include-not-supported` | error | `<mj-include>` wird nicht unterstützt. |
| `mjml.missing-attribute` | error oder warning | Ein erforderliches Attribut fehlt. Ein Fehler bei `<mj-font>` `name` und `href`, `<mj-class>` `name`, `<mj-selector>` `path` und `<mj-html-attribute>` `name`. Eine Warnung bei `src` eines Bilds und bei `<mj-breakpoint>` `width`. |
| `mjml.missing-title` | warning | Kein `<mj-title>` in `<mj-head>`. |
| `mjml.empty-title` | warning | `<mj-title>` ist leer. |
| `mjml.duplicate-head` | warning | Mehr als ein `<mj-head>`. |
| `mjml.ignored-content` | warning | Text in einem Element, das keinen Inhalt annimmt. |
| `mjml.ignored-children` | warning | Kindelemente in einem Element, das nur Inhalt annimmt. |
| `mjml.column-widths` | warning | Die Spaltenbreiten in einem Abschnitt oder einer Gruppe ergeben zusammen mehr als 100 %. |
| `mjml.unknown-social-network` | warning | Ein Name in `<mj-social-element>` ohne integriertes Symbol und ohne `src`. |
| `mjml.script` | warning | `<script>` im Inhalt. E-Mail-Clients entfernen es. |
| `mjml.missing-preview` | info | Kein `<mj-preview>`. |
| `mjml.missing-alt` | info | Ein `<mj-image>` ohne `alt`. |
| `mjml.button-without-link` | info | Ein `<mj-button>` ohne `href`. |

**Temple**

| Code | Schweregrad | Bedeutung |
| --- | --- | --- |
| `temple.unclosed-if` | error | `{{#if}}` ohne `{{/if}}`. |
| `temple.endif-without-if` | error | `{{/if}}` ohne `{{#if}}`. |
| `temple.else-without-if` | error | `{{else}}` außerhalb eines Blocks. |
| `temple.duplicate-else` | error | Zwei `{{else}}` in einem Block. |
| `temple.unclosed-expression` | error | `{{` ohne `}}`. |
| `temple.empty-expression` | error | `{{ }}`. |
| `temple.empty-condition` | error | `{{#if}}` ohne Variable. |
| `temple.malformed-else` | error | `{{else}}` mit Leerzeichen oder Argumenten geschrieben. |
| `temple.unsupported-block` | error | Ein anderer Block als `{{#if}}`, etwa `{{#each}}`. |
| `temple.unsupported-syntax` | error | Dreifache geschweifte Klammern `{{{…}}}`, Partials `{{> …}}` oder Kommentare `{{! …}}`. |
| `temple.invalid-variable` | warning | Eine Variable, die kein gültiger Pfad ist. |
| `temple.invalid-condition` | warning | Eine Bedingung, die kein Variablenpfad ist. Vergleiche werden nicht unterstützt. |
| `temple.block-crosses-components` | warning | Ein Block, der in einer Komponente beginnt und in einer anderen endet. |

**Dokument und Compiler**

| Code | Schweregrad | Bedeutung |
| --- | --- | --- |
| `document.empty` | error | Die Quelle ist leer. |
| `document.unrecognized` | error | Weder MJML-Markup noch MJML-JSON noch ein Emailit-MJML-Dokument. |
| `document.invalid-json` | error | Die Quelle sieht wie JSON aus, lässt sich aber nicht parsen. |
| `document.invalid-node` | error | MJML-JSON mit einem fehlerhaften Knoten. |
| `document.too-large` | error | Die Quelle ist größer als 2 MB. |
| `document.unsupported-schema` | error | Die `schema_version` der Hülle ist neuer als die, die Emailit lesen kann. |
| `document.unsupported-mjml-version` | error | Die MJML-Version des Dokuments lässt sich nicht kompilieren. Siehe [Versionen und Upgrades](#versions-and-upgrades). |
| `document.assumed-mjml-version` | info | Die Hülle hat keine `mjml_version`, daher wird die aktuelle Version angenommen. |
| `document.mjml-upgraded` | info | Für eine andere MJML-Version geschrieben und mit 5.4.1 kompiliert. |
| `compiler.failed` | error | MJML konnte das Dokument nicht rendern. |
| `compiler.gmail-clipping` | warning | Das HTML ist größer als 102 KB, daher kürzt Gmail es. |

## Temple in MJML

Die Tags von [Temple](/de/docs/templates/temple/) durchlaufen die MJML-Kompilierung unverändert. Emailit rendert sie beim Senden für jeden Empfänger, auf dem kompilierten HTML.

### Variablen in Inhalten und Attributen

Variablen funktionieren im Inhalt und in jedem Attribut:

```xml
<mj-text>Hi {{first_name|"there"}},</mj-text>
<mj-button href="{{activation_url}}">Activate your account</mj-button>
<mj-image src="{{logo_url}}" alt="{{company|'Acme'}}" />
<mj-section background-color="{{brand_color|'#ffffff'}}">
```

- Schreiben Sie Standardwerte innerhalb eines Attributs mit einfachen Anführungszeichen: `href="{{url|'https://example.com'}}"`.
- Attributwerte, die Temple enthalten, werden nicht auf ihren Typ geprüft, weil der Wert erst beim Senden feststeht. Stellen Sie sicher, dass die Variable einen Wert enthält, der für das Attribut gültig ist, etwa eine Farbe für `background-color`.
- Werte werden unverändert eingefügt, ohne HTML-Escaping.

### Bedingungsblöcke

Innerhalb einer Komponente setzen Sie den Block in ihren Inhalt:

```xml
<mj-text>{{#if plan}}You are on the {{plan}} plan.{{else}}You are on the free plan.{{/if}}</mj-text>
```

Um ganze Komponenten ein- oder auszublenden, setzen Sie die Block-Tags in `<mj-raw>`-Elemente auf derselben Ebene:

```xml
<mj-raw>{{#if vip}}</mj-raw>
<mj-section background-color="#fef3c7">
  <mj-column>
    <mj-text>Your VIP perks are ready.</mj-text>
  </mj-column>
</mj-section>
<mj-raw>{{/if}}</mj-raw>
```

Freistehende Block-Tags zwischen Komponenten werden beim Parsen des Markups in `<mj-raw>` umgewandelt. Das hier ist also dasselbe:

```xml
{{#if vip}}
<mj-section background-color="#fef3c7">
  …
</mj-section>
{{/if}}
```

Anderer Text zwischen Komponenten wird von MJML ignoriert und als `xml.stray-text` gemeldet.

- Blöcke müssen im gesamten Dokument ausgeglichen sein. Ein nicht geschlossenes oder überzähliges Tag ist ein Fehler.
- Öffnen und schließen Sie jeden Block im Inhalt einer einzigen Komponente oder zwischen den `<mj-raw>`-Elementen desselben Elternelements. Ein Block, der in einer Komponente beginnt und in einer anderen endet, erhält die Warnung `temple.block-crosses-components`, weil sein Ausblenden mitten durch die HTML-Struktur schneiden würde.
- Blöcke lassen sich verschachteln.

### Nicht unterstützt

- `<mj-include>` wird mit `mjml.include-not-supported` abgelehnt. Fügen Sie das eingebundene MJML direkt in das Dokument ein.
- Tags und Attribute, die MJML 5.4.1 nicht definiert, sind Fehler.
- Temple hat keine Schleifen, Helper, Partials, Kommentare, dreifachen geschweiften Klammern oder Vergleiche. Siehe [Temple](/de/docs/templates/temple/).

### Variablen nach Kanal

Dieselbe MJML-Vorlage kann von mehreren Stellen aus gesendet werden, und jede liefert andere Variablen:

| Gesendet über | Variablen |
| --- | --- |
| API, [E-Mail senden](/de/docs/api-reference/emails/send/) mit `template` | Das übergebene Objekt `variables` |
| Automatisierung, Schritt **Send email** | Automatisierungen mit Kontakten: die Felder des Kontakts auf oberster Ebene (`{{first_name}}`, `{{email}}`), eigene Felder als `{{cf.<key>}}` oder `{{custom_fields.<key>}}`, dazu `{{contact.*}}`, `{{payload.*}}` und `{{meta.*}}` |
| MJML-Kampagnen | `{{first_name}}`, `{{last_name}}`, `{{email}}`, `{{unsubscribe_url}}`, `{{cf.<key>}}` und dieselben Felder unter `{{contact.*}}` |

Die Editoren fügen eigene Felder als `{{cf.<key>}}` ein. Das funktioniert in MJML-Kampagnen und in Automatisierungen. Bei Versänden per API übergeben Sie die Variablen selbst.

Um die Version eines Empfängers in der Vorschau zu sehen, rufen Sie [MJML rendern](/de/docs/api-reference/mjml/render/) mit `variables` auf.

## Kampagnen

Eine Kampagne mit `content_type: "mjml"` speichert ihr MJML in `content`, in einem der [Quellformate](#source-formats), und Emailit kompiliert ihr `html`. Wie bei Vorlagen wird ein übergebenes `html` ignoriert. Ungültiges MJML gibt `422` mit `errors.content` und `diagnostics` zurück. Wenn Sie einen leeren `content` senden, werden sowohl der Inhalt als auch das HTML geleert. Antworten zu Kampagnen enthalten dasselbe Objekt `mjml` wie bei Vorlagen.

MJML-Kampagnen rendern Betreff, HTML und Text für jeden Empfänger mit **Temple**, auch bei Testversänden. Diese Variablen stehen zur Verfügung:

| Variable | Wert |
| --- | --- |
| `{{first_name}}` | Vorname des Kontakts |
| `{{last_name}}` | Nachname des Kontakts |
| `{{email}}` | E-Mail-Adresse des Kontakts |
| `{{unsubscribe_url}}` | Abmeldelink für diesen Kontakt und diese Kampagne |
| `{{cf.<key>}}` | Eigenes Feld des Kontakts, zum Beispiel `{{cf.company}}` |
| `{{contact.first_name}}`, `{{contact.cf.<key>}}`, … | Dieselben Felder unter `contact` |

Leere Kontaktfelder gelten als fehlend, daher greifen Standardwerte: `{{first_name|"there"}}` ergibt `there` bei einem Kontakt ohne Vornamen. Behalten Sie in Marketing-E-Mails einen Link mit `{{unsubscribe_url}}` in der Fußzeile.

Klassische Kampagnen (HTML, Text und die anderen Editoren) behalten die festen Platzhalter:

| | Klassische Kampagnen | MJML-Kampagnen |
| --- | --- | --- |
| Engine | Feste Platzhalter | Temple |
| `{{#if}}` … `{{else}}` … `{{/if}}` | Nicht verarbeitet | Unterstützt |
| Standardwerte wie `{{first_name\|"there"}}` | Nicht verarbeitet | Unterstützt. Leere Felder gelten als fehlend. |
| Groß-/Kleinschreibung | `{{FIRST_NAME}}` funktioniert | Pfade unterscheiden Groß- und Kleinschreibung |
| Unbekannte Tags | Bleiben unverändert in der Nachricht | Werden leer gerendert |

Wenn Sie in der Weboberfläche eine Kampagne aus einer MJML-Vorlage starten, wird das MJML-Dokument der Vorlage in die Kampagne kopiert.

### Ohne MJML-Zugriff

Während der Alpha kompiliert Emailit das MJML von Kampagnen nur für das Emailit-Team. Für alle anderen, auch für API-Schlüssel, bleibt `content_type: "mjml"` die reine Bezeichnung, die es vor der Alpha war: `content` wird so gespeichert, wie Sie es senden, Sie senden das kompilierte HTML in `html`, und Versände verwenden die klassischen Platzhalter. Wenn Sie eine Kampagne aus einer MJML-Vorlage starten, wird das HTML der Vorlage in eine HTML-Kampagne kopiert.

## Automatisierungen

Der Schritt **Send email** verweist über ihre ID (`tem_…`) auf eine Vorlage. MJML-Vorlagen funktionieren wie alle anderen: Der Schritt sendet das kompilierte HTML der Vorlage und rendert Temple mit den Variablen der Automatisierung. Siehe [E-Mails aus Automatisierungen](/de/docs/templates/temple/#automation-emails).

In den Einstellungen des Schritts erstellt **Design a new email** eine MJML-Vorlage aus einem Startdesign, wählt sie für den Schritt aus und öffnet sie im Visual Editor. **Edit email** öffnet die ausgewählte MJML-Vorlage. Änderungen wirken auf die Vorlage selbst, sodass jeder Schritt und jeder API-Aufruf, der die Vorlage verwendet, sie übernimmt. Ohne MJML-Zugriff zeigt der Schritt stattdessen einen Link zur Vorlage.

## Gemeinsam bearbeiten

Alle, die dieselbe gespeicherte MJML-Vorlage oder -Kampagne öffnen, bearbeiten in Echtzeit einen gemeinsamen Entwurf, in beiden Editoren:

- **Anwesenheit**: Die Kopfzeile zeigt, wer außerdem bearbeitet und was die anderen gerade tun. Im Visual Editor sehen Sie ihre Auswahl, ihre Cursor und eine kurze Hervorhebung in ihrer Farbe, wo sie etwas ändern. **Layers** zeigt, wer eine Komponente ausgewählt hat. Wählen Sie den Avatar einer Person, um zu ihrer Auswahl zu springen.
- **Änderungen werden zusammengeführt**: Änderungen an verschiedenen Komponenten, Attributen oder Textteilen werden kombiniert, statt sich gegenseitig zu überschreiben. Während jemand auf der Arbeitsfläche in einen Text tippt, ist dieser Text für andere gesperrt.
- **Code Editor**: Ihre Änderungen fließen beim Tippen in den gemeinsamen Entwurf ein. Änderungen anderer erscheinen in Ihrem Code, sobald Sie eine Tipppause machen, damit Ihr Cursor nicht springt. Enthält Ihr Code einen Syntaxfehler, warten sie, bis Sie ihn behoben haben.
- **Rückgängig und Wiederholen** wirken nur auf Ihre eigenen Änderungen.
- **Speichern**: Es gibt ein einziges **Save** für alle. Die Kopfzeile zeigt ungespeicherte Änderungen für den gesamten Entwurf und wer zuletzt gespeichert hat. Der Versand verwendet immer die gespeicherte Version.
- **Der Entwurf bleibt erhalten**: Wenn Sie den Editor schließen oder die Verbindung verlieren, gehen keine Änderungen verloren. Sie bleiben im gemeinsamen Entwurf und werden synchronisiert, sobald Sie wieder online sind. Beim erneuten Öffnen des Editors werden ungespeicherte Änderungen wiederhergestellt, und Sie können sie verwerfen, um zur gespeicherten Version zurückzukehren.
- **Anderswo gespeichert**: Wird die Vorlage oder Kampagne außerhalb des Editors gespeichert (per API, MCP oder **Edit with AI**), während sie geöffnet ist, wechselt ein Entwurf ohne ungespeicherte Änderungen zur gespeicherten Version. Ein Entwurf mit ungespeicherten Änderungen behält sie und bietet **Load saved version** oder **Keep this draft** an.
- **Gelöscht**: Wird die Vorlage oder Kampagne gelöscht oder ist sie kein MJML mehr, während Sie sie bearbeiten, teilt Ihnen der Editor das mit und lässt Sie das MJML kopieren.

Gemeinsames Bearbeiten erfordert gespeichertes, gültiges MJML. Eine Vorlage oder Kampagne, deren MJML sich nicht parsen lässt oder die noch nicht als MJML gespeichert ist, öffnet sich ohne diese Funktion: Jede Person bearbeitet allein, und das letzte Speichern gewinnt. Der Editor weist in einem Banner darauf hin. In einem gesperrten Workspace sind die Editoren schreibgeschützt.

## Versionen und Upgrades

Emailit kompiliert mit jeweils einer MJML-Version, derzeit 5.4.1. Jedes gespeicherte Dokument hält die `mjml_version` fest, auf die es ausgelegt ist, und Emailit prüft sie bei jeder Kompilierung des Dokuments:

| `mjml_version` des Dokuments | Ergebnis |
| --- | --- |
| 5.4.1 | Unverändert kompiliert |
| Fehlt | 5.4.1 wird angenommen (`document.assumed-mjml-version`, info) |
| Ein anderes 5.x-Release | Mit 5.4.1 kompiliert (`document.mjml-upgraded`, info) |
| 4.x | Zu MJML 5 migriert, dann mit 5.4.1 kompiliert (`document.mjml-upgraded`, info). MJML 4 und 5 haben dieselben Komponenten und Attribute; die HTML-Ausgabe unterscheidet sich leicht. |
| 3.x oder älter | Abgelehnt mit `document.unsupported-mjml-version` |
| Eine neuere Hauptversion | Abgelehnt mit `document.unsupported-mjml-version` |

Ein Dokument, dessen `schema_version` neuer ist als die, die Emailit lesen kann, wird mit `document.unsupported-schema` abgelehnt. Beim Speichern wird das Dokument mit der aktuellen `mjml_version` und `schema_version` gespeichert. Prüfen Sie nach einem Upgrade die Vorschau.

Die Editoren zeigen ihre Version und ihr Changelog an. Wurde ein Dokument mit einer neueren Editor-Version gespeichert als der der geöffneten Seite, fordert der Editor Sie auf, die Seite neu zu laden.

## MJML für KI-Agenten

[MJML-Referenz abrufen](/de/docs/api-reference/mjml/reference/) gibt Tools und KI-Modellen, was sie brauchen, um gültiges MJML für Emailit zu schreiben: jede Komponente mit ihren erlaubten Eltern- und Kindelementen und Attributen (Typ und Standardwert), den Temple-Leitfaden, Regeln zum Verfassen von MJML und einen kompakten Nur-Text `reference_text` für Prompts.

Auf dem [MCP-Server](/de/docs/mcp/) erhalten Sitzungen des Emailit-Teams außerdem diese Tools im Toolset `templates`:

| Tool | Beschreibung |
| --- | --- |
| `get-mjml-reference` | Die Referenz als Text: die MJML- und Editor-Versionen, Regeln zum Verfassen, der Temple-Leitfaden und die Komponentenreferenz. |
| `validate-mjml` | [MJML validieren](/de/docs/api-reference/mjml/validate/): `valid` und die Diagnosen. |
| `render-mjml` | [MJML rendern](/de/docs/api-reference/mjml/render/): das kompilierte HTML und, mit `variables`, `rendered_html`. |
| `create-template`, `update-template` | Nehmen außerdem `editor: "mjml"` und `source` an, das MJML-Markup oder MJML-JSON als String. Emailit kompiliert das HTML. |
| `create-campaign`, `update-campaign` | Nehmen außerdem `content_type: "mjml"` mit dem MJML in `content` an. |

Scheitert ein Speichern an der Validierung, listet der Tool-Fehler die Diagnosen der Stufen Fehler und Warnung mit ihren Zeilennummern auf, damit der Agent die Quelle korrigieren kann. Ein typischer Ablauf: die Referenz lesen, das MJML schreiben, `validate-mjml` aufrufen, bis `valid` den Wert `true` hat, mit `create-template` speichern und dann mit `render-mjml` die Version eines Empfängers prüfen. Andere Sitzungen sehen diese Tools und Parameter nicht.

## In der Weboberfläche

- **Vorlagen**: Erstellen Sie eine Vorlage und wählen Sie **MJML Visual Editor (Alpha)** oder **MJML Code Editor (Alpha)**.
- **Visual Editor**: Drag-and-drop auf der gerenderten E-Mail, ein Ebenenbaum, ein Eigenschaftenbereich für jedes MJML-Attribut, Dokumenteinstellungen (Head, Schriften, Stile und Standardattribute), Temple-Variablen in jeder Eigenschaft und Bedingungsblöcke um Komponenten.
- **Code Editor**: Autovervollständigung für MJML-Tags, Attribute, Werte und Temple, Inline-Validierung mit Schnellkorrekturen und Formatierung.
- **Beide Editoren**: eine Live-Vorschau für Desktop und Mobilgeräte, im Browser mit MJML 5.4.1 kompiliert, eine Vorschau mit Beispieldaten (Temple gerendert), eine Problemliste und ein KI-Assistent, wenn er aktiviert ist. Sie können für dasselbe Dokument zwischen Visual und Code wechseln; der Wechsel zu Visual erfordert Code ohne Syntaxfehler. Speichern ist blockiert, solange das MJML Fehler enthält.
- **Gemeinsam bearbeiten**: Teammitglieder, die dieselbe Vorlage oder Kampagne öffnen, bearbeiten sie in Echtzeit. Siehe [Gemeinsam bearbeiten](#editing-together).
- **Edit with AI**: Beschreiben Sie eine Änderung an einer MJML-Vorlage oder -Kampagne, ohne den Editor zu öffnen.
- **Import**: eine `.mjml`-Datei, eine `.json`-Datei mit MJML-JSON oder einem Emailit-MJML-Dokument oder ein ZIP mit `template.mjml` und einem Ordner `images/` auf oberster Ebene.
- **Export**: MJML (Markup), MJML-JSON (das gespeicherte Dokument), HTML oder ein ZIP mit `template.mjml`, `template.html` und `images/`. Der Export funktioniert für alle.
- **Kampagnen**: Wählen Sie für den Inhalt der Kampagne den MJML Visual Editor oder den MJML Code Editor.
- **Automatisierungen**: Gestalten Sie die E-Mail eines Schritts **Send email** direkt dort. Siehe [Automatisierungen](#automations).

## Siehe auch

- [Vorlagen erstellen und bearbeiten](/de/docs/templates/editors/)
- [Template-Sprache Temple](/de/docs/templates/temple/)
- [API-Referenz für MJML](/de/docs/api-reference/mjml/)
- [Import und Export](/de/docs/templates/import-export/)

---
Quelle: https://emailit.com/de/docs/templates/mjml/
