# Editor e API MJML

> Crea template e campagne responsive con MJML, in alpha e aperto solo al team di Emailit. Il Visual Editor e il Code Editor, i documenti memorizzati, la convalida, Temple in MJML, la modifica condivisa in tempo reale e l’API MJML.

[MJML](https://mjml.io) è un linguaggio di markup per email responsive. Scrivi sezioni, colonne e componenti come `<mj-text>` e `<mj-button>`, e MJML li compila in un HTML che viene visualizzato in modo coerente nei vari client di posta. In Emailit, MJML può essere il sorgente di un template o di una campagna: lo scrivi negli editor del pannello o lo invii tramite l’API, ed Emailit lo convalida e ne compila l’HTML.

> **MJML è in alpha:** MJML è in alpha e aperto solo al team di Emailit mentre lo testiamo. I workspace dei clienti non vedono ancora gli editor MJML, e le richieste API che creano o modificano template MJML, o che chiamano gli endpoint MJML, restituiscono `403` con `error: "mjml_alpha"`. Questa pagina descrive come funziona MJML, così puoi pianificarne l’uso. I template e le campagne creati con MJML vengono comunque inviati per tutti.

## Panoramica

- **Template**: `editor: "mjml"` con l’MJML in `source`. Vedi [Crea un template](/it/docs/api-reference/templates/create/).
- **Campagne**: `content_type: "mjml"` con l’MJML in `content`. Vedi [Campagne](#campaigns).
- **Automazioni**: il passaggio **Send email** invia un template MJML come qualsiasi altro template. Vedi [Automazioni](#automations).
- **Endpoint MJML**: [Convalida l’MJML](/it/docs/api-reference/mjml/validate/), [Elabora l’MJML](/it/docs/api-reference/mjml/render/) e [Recupera il riferimento MJML](/it/docs/api-reference/mjml/reference/).

### Chi può usare MJML

Durante l’alpha, MJML è disponibile solo per gli amministratori della piattaforma Emailit. Il ruolo Admin di un workspace non basta.

| Dove | Team di Emailit | Tutti gli altri |
| --- | --- | --- |
| Pannello | Editor MJML, importazione MJML, **Edit with AI** e modifica condivisa in tempo reale | Nessun editor MJML. Un template o una campagna MJML mostra una nota, non si può aprire in un editor e viene comunque inviato. |
| API | Template MJML, campagne MJML e gli endpoint MJML | `403` con `error: "mjml_alpha"`. Il `content_type: "mjml"` di una campagna resta una semplice etichetta, come prima dell’alpha. Vedi [Campagne](#campaigns). |
| Chiavi API | Nessuna. Le chiavi API appartengono a un workspace, non a una persona. | `403` con `error: "mjml_alpha"` |
| Server MCP | Gli strumenti MJML e i parametri MJML degli strumenti per template e campagne | Non elencati |

Tutti possono comunque rinominare, pubblicare, esportare, inviare ed eliminare template e campagne MJML. Duplicare un template MJML crea un nuovo template MJML, quindi richiede l’accesso a MJML.

### Versione di MJML

Emailit compila tutto l’MJML con **MJML 5.4.1**, sia sul server sia nell’anteprima dal vivo degli editor. La convalida controlla tag, attributi e valori degli attributi rispetto a quella versione. [Recupera il riferimento MJML](/it/docs/api-reference/mjml/reference/) restituisce la versione e ogni componente e attributo che supporta.

### Editor

Il pannello ha due editor MJML. Entrambi hanno un numero di versione ed entrambi sono versioni alpha `0.x`.

| Editor | ID | Versione | Descrizione |
| --- | --- | --- | --- |
| MJML Visual Editor | `mjml-visual` | 0.2.0 (alpha) | Drag and drop sull’email visualizzata, per ogni componente e attributo MJML |
| MJML Code Editor | `mjml-code` | 0.2.0 (alpha) | MJML con completamento automatico, convalida in linea e un’anteprima dal vivo per desktop e mobile |

Entrambi gli editor salvano un template con `editor: "mjml"`. Il documento memorizzato registra quale editor, e quale sua versione, lo ha salvato per ultimo. I membri del team possono modificare lo stesso template o la stessa campagna nello stesso momento. Vedi [Modifica condivisa](#editing-together).

## Formati del sorgente

Ovunque Emailit accetti MJML (il `source` di un template, il `content` di una campagna e il campo `source` degli endpoint MJML), puoi inviare uno qualsiasi di questi formati:

| Formato | Esempio |
| --- | --- |
| Markup MJML | Una stringa che inizia con `<mjml>`. Sono ammessi una dichiarazione XML o commenti iniziali. |
| MJML JSON | Il formato JSON di MJML, come oggetto o come stringa JSON: `{ "tagName": "mjml", "attributes": {}, "children": [ … ] }`. Gli ending tag come `mj-text` hanno il loro HTML in `content`. |
| Documento MJML di Emailit | L’involucro che Emailit memorizza (vedi sotto), come oggetto o come stringa JSON |

Qualsiasi altro formato viene rifiutato con `document.unrecognized`. I sorgenti più grandi di 2 MB vengono rifiutati con `document.too-large`.

### Il documento memorizzato

Emailit memorizza l’MJML in un involucro con versione. È il `source` del template e il `content` della campagna:

```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>"
}
```

| Campo | Descrizione |
| --- | --- |
| `kind` | Sempre `emailit/mjml`. |
| `schema_version` | Versione della struttura dell’involucro. Attualmente `1`. |
| `mjml_version` | La release di MJML a cui è destinato il contenuto. Emailit la imposta sulla versione con cui ha compilato. |
| `editor` | Cosa ha scritto il documento per ultimo: `mjml-visual`, `mjml-code`, `ai` (**Edit with AI**) o `api` (l’API, gli strumenti MCP e le importazioni da file). |
| `editor_version` | Versione di quell’editor, oppure `null`. |
| `format` | `markup`: `content` è markup MJML, conservato così come è scritto, commenti e formattazione compresi. `json`: `content` è MJML JSON. |
| `content` | L’MJML. |

Il formato dipende da ciò che invii: il markup viene memorizzato come `markup` e l’MJML JSON come `json`. In entrambi i casi viene registrato `editor: "api"`. Un involucro che invii mantiene i suoi `editor` ed `editor_version`.

Le risposte dell’API restituiscono `source` come questo involucro, serializzato in una stringa JSON, e puoi rimandarlo senza modifiche. Le risposte includono anche un oggetto `mjml` con le versioni dell’involucro:

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

Il pannello apre un documento nell’editor che lo ha salvato per ultimo. I documenti scritti tramite l’API si aprono nel Code Editor quando `format` è `markup` e nel Visual Editor quando è `json`.

## Compilazione e salvataggio

Per i template e le campagne MJML, è Emailit a gestire l’HTML:

- Alla creazione e all’aggiornamento, Emailit convalida l’MJML e lo compila. L’HTML compilato viene memorizzato come `html` del template, e qualsiasi `html` che invii viene ignorato.
- L’invio usa l’HTML memorizzato. I tag Temple vi restano e vengono elaborati per ogni destinatario al momento dell’invio.
- Aggiornare solo altri campi, come `name` o `subject`, non ricompila l’MJML.
- `text` non viene generato dall’MJML. Invia tu `text` se vuoi una parte in testo semplice.
- Passare un template esistente a `editor: "mjml"` senza inviare `source` compila il `source` memorizzato del template, che deve quindi essere MJML.

L’HTML viene compilato al salvataggio, quindi l’HTML di un template esistente cambia solo quando lo salvi di nuovo.

```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>"
  }'
```

Poi invialo come qualsiasi altro template con [Invia un’email](/it/docs/api-reference/emails/send/): `"template": "welcome"` e un oggetto `variables`.

## Convalida

Ogni salvataggio esegue gli stessi controlli di [Convalida l’MJML](/it/docs/api-reference/mjml/validate/):

- Sintassi XML: tag non chiusi o non corrispondenti e attributi malformati (`xml.*`)
- Struttura, attributi e valori degli attributi MJML per MJML 5.4.1 (`mjml.*`)
- Sintassi Temple e blocchi `{{#if}}` bilanciati (`temple.*`)
- Il formato del sorgente e le versioni (`document.*`), e il compilatore stesso (`compiler.*`)

Ogni problema rilevato è una diagnostica con una gravità:

| Gravità | Effetto |
| --- | --- |
| `error` | L’MJML viene rifiutato. Template e campagne non vengono salvati. |
| `warning` | Salvato. Probabilmente è un errore: nessun `<mj-title>`, testo fuori da un componente, un blocco condizionale che attraversa più componenti, o un HTML oltre i 102 KB, il limite oltre il quale Gmail tronca i messaggi. |
| `info` | Salvato. Un suggerimento o una nota: nessun `<mj-preview>`, un’immagine senza `alt`, o un documento scritto per una versione precedente di MJML. |

Una diagnostica ha questi campi. I campi che non si applicano vengono omessi.

| Campo | Descrizione |
| --- | --- |
| `severity` | `error`, `warning` o `info` |
| `code` | Un codice stabile, leggibile dalle macchine, ad esempio `mjml.invalid-child` |
| `message` | Una spiegazione leggibile, spesso con una correzione («Did you mean color?») |
| `line`, `column` | Posizione nel markup, a partire da 1. Solo per i sorgenti in markup. |
| `tag` | L’elemento a cui si riferisce la diagnostica |
| `attribute` | L’attributo, quando c’è |
| `path` | Percorso di indici dei figli a partire dalla radice `<mjml>`. `[0, 1]` è il secondo figlio del primo figlio. |

### Risposta di errore

Il salvataggio di un template o di una campagna con diagnostiche di errore restituisce `422`. Per questo sorgente:

```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>
```

la risposta è:

```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` per le campagne) elenca fino a cinque messaggi di errore, con la riga quando è nota.
- `diagnostics` elenca tutte le diagnostiche, compresi avvisi e informazioni.
- Un sorgente mancante o vuoto restituisce `422` con `"message": "Validation failed"`, `"errors": { "source": ["The source field is required for MJML."] }` e un array `diagnostics` vuoto.

[Convalida l’MJML](/it/docs/api-reference/mjml/validate/) esegue gli stessi controlli senza salvare e restituisce `200` con `valid: false` invece di `422`.

### Codici delle diagnostiche

**XML** (sorgenti in markup)

| Codice | Gravità | Significato |
| --- | --- | --- |
| `xml.unclosed-tag` | error | Un elemento non viene mai chiuso. |
| `xml.unexpected-closing-tag` | error | Un tag di chiusura non corrisponde a nessun elemento aperto. |
| `xml.malformed-closing-tag` | error | Un tag di chiusura non si riesce a leggere. |
| `xml.unterminated-tag` | error | Un tag di apertura non ha la `>` di chiusura. |
| `xml.unterminated-attribute` | error | Il valore di un attributo non ha le virgolette di chiusura. |
| `xml.missing-attribute-value` | error | `name=` non ha un valore. |
| `xml.invalid-attribute` | error | Un carattere inatteso dentro un tag. |
| `xml.duplicate-attribute` | error | Lo stesso attributo due volte sullo stesso elemento. Viene usato il primo. |
| `xml.unterminated-comment` | error | Un commento non ha `-->`. |
| `xml.unterminated-cdata` | error | Una sezione CDATA non ha `]]>`. |
| `xml.unexpected-character` | error | Un `<` isolato fuori da un ending tag. |
| `xml.multiple-roots` | error | Più di un elemento radice. |
| `xml.text-outside-root` | error | Testo fuori da `<mjml>`. |
| `mjml.missing-root` | error | Il documento è vuoto. |
| `xml.unquoted-attribute` | warning | Il valore di un attributo senza virgolette. |
| `xml.stray-text` | warning | Testo tra gli elementi, fuori da qualsiasi componente di contenuto. MJML lo ignora. |
| `xml.unexpected-declaration` | warning | Una dichiarazione dopo l’inizio di `<mjml>`. |

**MJML**

| Codice | Gravità | Significato |
| --- | --- | --- |
| `mjml.unknown-tag` | error | Non è un elemento di MJML 5.4.1, con un suggerimento «did you mean» quando ce n’è uno simile. |
| `mjml.unknown-attribute` | error | L’elemento non ha questo attributo. Su `<mjml>` stesso è un avviso. |
| `mjml.invalid-attribute-value` | error | Un tipo di valore sbagliato: non è un colore, un’unità o un valore consentito. |
| `mjml.invalid-child` | error | L’elemento non è consentito all’interno del suo genitore. |
| `mjml.invalid-root` | error | L’elemento radice non è `<mjml>`. |
| `mjml.missing-body` | error | Nessun `<mj-body>`. |
| `mjml.duplicate-body` | error | Più di un `<mj-body>`. |
| `mjml.include-not-supported` | error | `<mj-include>` non è supportato. |
| `mjml.missing-attribute` | error o warning | Manca un attributo obbligatorio. È un errore per `name` e `href` di `<mj-font>`, `name` di `<mj-class>`, `path` di `<mj-selector>` e `name` di `<mj-html-attribute>`. È un avviso per `src` di un’immagine e `width` di `<mj-breakpoint>`. |
| `mjml.missing-title` | warning | Nessun `<mj-title>` in `<mj-head>`. |
| `mjml.empty-title` | warning | `<mj-title>` è vuoto. |
| `mjml.duplicate-head` | warning | Più di un `<mj-head>`. |
| `mjml.ignored-content` | warning | Testo dentro un elemento che non accetta contenuto. |
| `mjml.ignored-children` | warning | Elementi figli dentro un elemento che accetta solo contenuto. |
| `mjml.column-widths` | warning | Le larghezze delle colonne di una sezione o di un gruppo superano in totale il 100%. |
| `mjml.unknown-social-network` | warning | Un nome di `<mj-social-element>` senza icona integrata e senza `src`. |
| `mjml.script` | warning | `<script>` nel contenuto. I client di posta lo rimuovono. |
| `mjml.missing-preview` | info | Nessun `<mj-preview>`. |
| `mjml.missing-alt` | info | Un `<mj-image>` senza `alt`. |
| `mjml.button-without-link` | info | Un `<mj-button>` senza `href`. |

**Temple**

| Codice | Gravità | Significato |
| --- | --- | --- |
| `temple.unclosed-if` | error | `{{#if}}` senza `{{/if}}`. |
| `temple.endif-without-if` | error | `{{/if}}` senza `{{#if}}`. |
| `temple.else-without-if` | error | `{{else}}` fuori da un blocco. |
| `temple.duplicate-else` | error | Due `{{else}}` nello stesso blocco. |
| `temple.unclosed-expression` | error | `{{` senza `}}`. |
| `temple.empty-expression` | error | `{{ }}`. |
| `temple.empty-condition` | error | `{{#if}}` senza una variabile. |
| `temple.malformed-else` | error | `{{else}}` scritto con spazi o argomenti. |
| `temple.unsupported-block` | error | Un blocco diverso da `{{#if}}`, come `{{#each}}`. |
| `temple.unsupported-syntax` | error | Triple parentesi graffe `{{{…}}}`, partial `{{> …}}` o commenti `{{! …}}`. |
| `temple.invalid-variable` | warning | Una variabile che non è un percorso valido. |
| `temple.invalid-condition` | warning | Una condizione che non è un percorso di variabile. I confronti non sono supportati. |
| `temple.block-crosses-components` | warning | Un blocco che si apre in un componente e si chiude in un altro. |

**Documento e compilatore**

| Codice | Gravità | Significato |
| --- | --- | --- |
| `document.empty` | error | Il sorgente è vuoto. |
| `document.unrecognized` | error | Non è markup MJML, MJML JSON né un documento MJML di Emailit. |
| `document.invalid-json` | error | Il sorgente sembra JSON ma non si riesce ad analizzarlo. |
| `document.invalid-node` | error | MJML JSON con un nodo malformato. |
| `document.too-large` | error | Il sorgente è più grande di 2 MB. |
| `document.unsupported-schema` | error | Il campo `schema_version` dell’involucro è più recente di quanto Emailit sappia leggere. |
| `document.unsupported-mjml-version` | error | La versione di MJML del documento non si può compilare. Vedi [Versioni e aggiornamenti](#versions-and-upgrades). |
| `document.assumed-mjml-version` | info | L’involucro non ha `mjml_version`, quindi viene presunta la versione corrente. |
| `document.mjml-upgraded` | info | Scritto per un’altra versione di MJML e compilato con la 5.4.1. |
| `compiler.failed` | error | MJML non è riuscito a elaborare il documento. |
| `compiler.gmail-clipping` | warning | L’HTML è più grande di 102 KB, quindi Gmail lo tronca. |

## Temple in MJML

I tag [Temple](/it/docs/templates/temple/) attraversano la compilazione MJML senza modifiche. Emailit li elabora per ogni destinatario al momento dell’invio, sull’HTML compilato.

### Variabili nel contenuto e negli attributi

Le variabili funzionano nel contenuto e in qualsiasi attributo:

```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'}}">
```

- Dentro un attributo, scrivi i valori predefiniti tra virgolette singole: `href="{{url|'https://example.com'}}"`.
- I valori degli attributi che contengono Temple non vengono controllati per tipo, perché il valore è noto solo al momento dell’invio. Assicurati che la variabile contenga un valore valido per l’attributo, come un colore per `background-color`.
- I valori vengono inseriti così come sono, senza escaping HTML.

### Blocchi condizionali

All’interno di un solo componente, metti il blocco nel suo contenuto:

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

Per mostrare o nascondere componenti interi, metti i tag del blocco in elementi `<mj-raw>` allo stesso livello:

```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>
```

I tag di blocco isolati tra i componenti vengono convertiti in `<mj-raw>` quando il markup viene analizzato, quindi questo è equivalente:

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

Il resto del testo tra i componenti viene ignorato da MJML e segnalato come `xml.stray-text`.

- I blocchi devono essere bilanciati nell’intero documento. Un tag non chiuso o in più è un errore.
- Apri e chiudi ogni blocco nel contenuto di un solo componente, o tra gli elementi `<mj-raw>` dello stesso genitore. Un blocco che si apre in un componente e si chiude in un altro riceve un avviso `temple.block-crosses-components`, perché nasconderlo spezzerebbe la struttura HTML.
- I blocchi si possono annidare.

### Non supportato

- `<mj-include>` viene rifiutato con `mjml.include-not-supported`. Incolla l’MJML incluso direttamente nel documento.
- I tag e gli attributi che MJML 5.4.1 non definisce sono errori.
- Temple non ha cicli, helper, partial, commenti, triple parentesi graffe né confronti. Vedi [Temple](/it/docs/templates/temple/).

### Variabili per canale

Lo stesso template MJML si può inviare da più punti, e ognuno fornisce variabili diverse:

| Inviato da | Variabili |
| --- | --- |
| API [Invia un’email](/it/docs/api-reference/emails/send/) con `template` | L’oggetto `variables` che passi |
| Passaggio **Send email** di un’automazione | Automazioni sui contatti: i campi del contatto al livello principale (`{{first_name}}`, `{{email}}`), i campi personalizzati come `{{cf.<key>}}` o `{{custom_fields.<key>}}`, più `{{contact.*}}`, `{{payload.*}}` e `{{meta.*}}` |
| Campagne MJML | `{{first_name}}`, `{{last_name}}`, `{{email}}`, `{{unsubscribe_url}}`, `{{cf.<key>}}` e gli stessi campi sotto `{{contact.*}}` |

Gli editor inseriscono i campi personalizzati come `{{cf.<key>}}`, che funziona nelle campagne MJML e nelle automazioni. Per gli invii con l’API, passa tu le variabili.

Per vedere in anteprima la versione di un destinatario, chiama [Elabora l’MJML](/it/docs/api-reference/mjml/render/) con `variables`.

## Campagne

Una campagna con `content_type: "mjml"` memorizza il suo MJML in `content`, in uno qualsiasi dei [formati del sorgente](#source-formats), ed Emailit ne compila l’`html`. Come per i template, qualsiasi `html` che invii viene ignorato. Un MJML non valido restituisce `422` con `errors.content` e `diagnostics`. Inviare un `content` vuoto cancella sia il contenuto sia l’HTML. Le risposte delle campagne includono lo stesso oggetto `mjml` dei template.

Le campagne MJML elaborano oggetto, HTML e testo con **Temple** per ogni destinatario, anche negli invii di prova. Sono disponibili queste variabili:

| Variabile | Valore |
| --- | --- |
| `{{first_name}}` | Nome del contatto |
| `{{last_name}}` | Cognome del contatto |
| `{{email}}` | Indirizzo email del contatto |
| `{{unsubscribe_url}}` | Link di disiscrizione per questo contatto e questa campagna |
| `{{cf.<key>}}` | Campo personalizzato del contatto, ad esempio `{{cf.company}}` |
| `{{contact.first_name}}`, `{{contact.cf.<key>}}`, … | Gli stessi campi sotto `contact` |

I campi vuoti del contatto contano come mancanti, quindi si applicano i valori predefiniti: `{{first_name|"there"}}` diventa `there` per un contatto senza nome. Tieni un link `{{unsubscribe_url}}` nel piè di pagina delle email di marketing.

Le campagne classiche (HTML, testo e gli altri editor) mantengono i tag di unione fissi:

| | Campagne classiche | Campagne MJML |
| --- | --- | --- |
| Motore | Tag di unione fissi | Temple |
| `{{#if}}` … `{{else}}` … `{{/if}}` | Non elaborati | Supportati |
| Valori predefiniti come `{{first_name\|"there"}}` | Non elaborati | Supportati. I campi vuoti contano come mancanti. |
| Maiuscole e minuscole | `{{FIRST_NAME}}` funziona | I percorsi distinguono tra maiuscole e minuscole |
| Tag sconosciuti | Restano nel messaggio così come sono scritti | Diventano vuoti |

Nel pannello, avviare una campagna da un template MJML copia il documento MJML del template nella campagna.

### Senza accesso a MJML

Durante l’alpha, Emailit compila l’MJML delle campagne solo per il team di Emailit. Per tutti gli altri, chiavi API comprese, `content_type: "mjml"` resta la semplice etichetta che era prima dell’alpha: `content` viene memorizzato così come lo invii, l’HTML compilato lo invii tu in `html`, e gli invii usano i tag di unione classici. Avviare una campagna da un template MJML copia l’HTML del template in una campagna HTML.

## Automazioni

Il passaggio **Send email** fa riferimento a un template tramite ID (`tem_…`). I template MJML funzionano come tutti gli altri: il passaggio invia l’HTML compilato del template ed elabora Temple con le variabili dell’automazione. Vedi [Email delle automazioni](/it/docs/templates/temple/#automation-emails).

Nelle impostazioni del passaggio, **Design a new email** crea un template MJML da un design di partenza, lo seleziona per il passaggio e lo apre nel Visual Editor. **Edit email** apre il template MJML selezionato. Le modifiche cambiano il template stesso, quindi valgono per ogni passaggio e chiamata API che usa il template. Senza accesso a MJML, il passaggio mostra invece un link al template.

## Modifica condivisa

Tutti quelli che aprono lo stesso template o la stessa campagna MJML salvati modificano un’unica bozza condivisa in tempo reale, in uno qualsiasi dei due editor:

- **Presenza**: l’intestazione mostra chi altro sta modificando e cosa sta facendo. Nel Visual Editor vedi le selezioni e i cursori degli altri, e una breve evidenziazione nel loro colore dove cambiano qualcosa. **Layers** mostra chi ha selezionato un componente. Seleziona l’avatar di qualcuno per passare alla sua selezione.
- **Le modifiche si uniscono**: le modifiche a componenti, attributi o parti di un testo diversi si combinano invece di sovrascriversi. Mentre qualcuno scrive in un testo sulla tela, quel testo è bloccato per gli altri.
- **Code Editor**: le tue modifiche confluiscono nella bozza condivisa mentre scrivi. Le modifiche degli altri compaiono nel tuo codice quando smetti di scrivere, così il cursore non salta. Se il tuo codice ha un errore di sintassi, aspettano finché non lo correggi.
- **Annulla e ripeti** annullano solo le tue modifiche.
- **Salvataggio**: c’è un solo **Save** per tutti. L’intestazione mostra le modifiche non salvate dell’intera bozza e chi ha salvato per ultimo. L’invio usa sempre la versione salvata.
- **La bozza viene conservata**: chiudere l’editor o perdere la connessione non fa perdere le modifiche. Restano nella bozza condivisa e si sincronizzano quando torni online. Riaprendo l’editor ritrovi le modifiche non salvate, e puoi scartarle per tornare alla versione salvata.
- **Salvato altrove**: quando il template o la campagna viene salvato fuori dall’editor (l’API, MCP o **Edit with AI**) mentre è aperto, una bozza senza modifiche non salvate passa alla versione salvata. Una bozza con modifiche non salvate le mantiene e offre **Load saved version** o **Keep this draft**.
- **Eliminato**: se il template o la campagna viene eliminato, o non è più MJML, mentre lo modifichi, l’editor te lo segnala e ti permette di copiare l’MJML.

La modifica condivisa richiede un MJML salvato e valido. Un template o una campagna il cui MJML non si riesce ad analizzare, o che non è ancora salvato come MJML, si apre senza: ognuno modifica da solo e vince l’ultimo salvataggio. L’editor lo segnala in un banner. In un workspace sospeso gli editor sono di sola lettura.

## Versioni e aggiornamenti

Emailit compila con una sola versione di MJML alla volta, attualmente la 5.4.1. Ogni documento memorizzato registra nel campo `mjml_version` la versione a cui è destinato, ed Emailit la controlla ogni volta che il documento viene compilato:

| `mjml_version` del documento | Risultato |
| --- | --- |
| 5.4.1 | Compilato così com’è |
| Assente | Viene presunta la 5.4.1 (`document.assumed-mjml-version`, info) |
| Un’altra release 5.x | Compilato con la 5.4.1 (`document.mjml-upgraded`, info) |
| 4.x | Migrato a MJML 5, poi compilato con la 5.4.1 (`document.mjml-upgraded`, info). MJML 4 e 5 hanno gli stessi componenti e attributi; l’HTML prodotto differisce leggermente. |
| 3.x o precedenti | Rifiutato con `document.unsupported-mjml-version` |
| Una versione major più recente | Rifiutato con `document.unsupported-mjml-version` |

Un documento il cui `schema_version` è più recente di quanto Emailit sappia leggere viene rifiutato con `document.unsupported-schema`. Il salvataggio memorizza il documento con i valori correnti di `mjml_version` e `schema_version`. Controlla l’anteprima dopo un aggiornamento.

Gli editor mostrano la loro versione e il loro changelog. Quando un documento è stato salvato con una versione dell’editor più recente di quella della pagina che hai aperto, l’editor ti chiede di ricaricarla.

## MJML per gli agenti AI

[Recupera il riferimento MJML](/it/docs/api-reference/mjml/reference/) fornisce agli strumenti di sviluppo e ai modelli AI ciò che serve per scrivere MJML valido per Emailit: ogni componente con i genitori, i figli e gli attributi consentiti (tipo e valore predefinito), la guida a Temple, le regole di scrittura e un `reference_text` compatto in testo semplice per i prompt.

Sul [server MCP](/it/docs/mcp/), le sessioni del team di Emailit ricevono anche questi strumenti nel toolset `templates`:

| Strumento | Descrizione |
| --- | --- |
| `get-mjml-reference` | Il riferimento come testo: le versioni di MJML e degli editor, le regole di scrittura, la guida a Temple e il riferimento dei componenti. |
| `validate-mjml` | [Convalida l’MJML](/it/docs/api-reference/mjml/validate/): `valid` e le diagnostiche. |
| `render-mjml` | [Elabora l’MJML](/it/docs/api-reference/mjml/render/): l’HTML compilato e, con `variables`, `rendered_html`. |
| `create-template`, `update-template` | Accettano anche `editor: "mjml"` e `source`, cioè il markup MJML o l’MJML JSON come stringa. Emailit compila l’HTML. |
| `create-campaign`, `update-campaign` | Accettano anche `content_type: "mjml"` con l’MJML in `content`. |

Quando un salvataggio non supera la convalida, l’errore dello strumento elenca le diagnostiche di errore e di avviso con i numeri di riga, così l’agente può correggere il sorgente. Un flusso tipico: leggere il riferimento, scrivere l’MJML, chiamare `validate-mjml` finché `valid` non è `true`, salvare con `create-template`, poi controllare la versione di un destinatario con `render-mjml`. Le altre sessioni non vedono questi strumenti né questi parametri.

## Nel pannello

- **Template**: crea un template e scegli **MJML Visual Editor (Alpha)** o **MJML Code Editor (Alpha)**.
- **Visual Editor**: drag and drop sull’email visualizzata, un albero dei livelli, un riquadro delle proprietà per ogni attributo MJML, le impostazioni del documento (head, font, stili e attributi predefiniti), variabili Temple in qualsiasi proprietà e blocchi condizionali attorno ai componenti.
- **Code Editor**: completamento automatico per tag, attributi e valori MJML e per Temple, convalida in linea con correzioni rapide, e formattazione.
- **Entrambi gli editor**: un’anteprima dal vivo per desktop e mobile compilata nel browser con MJML 5.4.1, un’anteprima con dati di esempio (con Temple elaborato), un elenco dei problemi e un assistente AI quando è attivo. Puoi passare tra Visual e Code sullo stesso documento; per passare a Visual il codice non deve avere errori di sintassi. Il salvataggio è bloccato finché l’MJML ha errori.
- **Modifica condivisa**: i membri del team che aprono lo stesso template o la stessa campagna lo modificano in tempo reale. Vedi [Modifica condivisa](#editing-together).
- **Edit with AI**: descrivi una modifica a un template o a una campagna MJML senza aprire l’editor.
- **Importazione**: un file `.mjml`, un file `.json` con MJML JSON o con un documento MJML di Emailit, oppure uno ZIP con `template.mjml` e una cartella `images/` nella radice.
- **Esportazione**: MJML (markup), MJML JSON (il documento memorizzato), HTML, oppure uno ZIP con `template.mjml`, `template.html` e `images/`. L’esportazione funziona per tutti.
- **Campagne**: scegli il Visual Editor o il Code Editor MJML per il contenuto della campagna.
- **Automazioni**: progetta l’email di un passaggio **Send email** direttamente lì. Vedi [Automazioni](#automations).

## Vedi anche

- [Crea e modifica i template](/it/docs/templates/editors/)
- [Il linguaggio di template Temple](/it/docs/templates/temple/)
- [Riferimento dell’API MJML](/it/docs/api-reference/mjml/)
- [Importazione ed esportazione](/it/docs/templates/import-export/)

---
Fonte: https://emailit.com/it/docs/templates/mjml/
