# Making HTML Editable

The drag-and-drop editor does not parse arbitrary HTML into blocks. It works on a small, fixed structure of sections, rows, and editable regions, marked with class names. This page shows the minimum structure the editor needs, ending with a complete template you can paste in and adapt.

---

## How the Editor Sees Your Email

```
<body class="nvkbody">
  div.nvkbody.wrapper                     the full-width wrapper
    table (680 wide)                      the email's content width
      td                                  holds the sections
        div.block-outer                   a section: moved, duplicated, deleted as a whole
          ...section tables...            background and column layout
            div.block-inner               a row: one block, such as a heading and text, an image, or a button
              table.inner-table           
                td.inner-column           the row's padding, background, and font
                  div.content-edit        the editable region: what the user clicks to edit
```

- A **section** (`block-outer`) holds one or more rows, in one column or several.
- A **row** (`block-inner`) is what the editor calls a block: users select, restyle, move, duplicate, and delete rows.
- An **editable region** (`content-edit`) holds the content. Its other classes say what kind of block the row is: text, image, button, divider, or video.

Content outside an editable region cannot be selected or edited in the drag-and-drop editor.

---

## The Head

```html
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="TEMPLATE_VERSION" content="230609">
<title>{@msg-subject}</title>
<style type="text/css" id="envoke-styles">
  /* Envoke's style block: copy it from "Envoke's Style Block" */
</style>
</head>
```

- `TEMPLATE_VERSION` makes the HTML open in the drag-and-drop editor (see [Two Editors](https://envoke-developers.pages.dev/email-html/overview/#two-editors)). Copy it exactly.
- `<title>{@msg-subject}</title>`, written exactly like this, is replaced by the message's subject when the email is sent.
- The style block with `id="envoke-styles"` gives your HTML the same base styles and mobile rules the editor uses. Copy it from [Envoke's Style Block](https://envoke-developers.pages.dev/email-html/css-and-mobile/#envokes-style-block). The editor replaces it with its current version every time the message is opened, so the copy you ship only matters until then, for example for HTML sent straight from the Send API.
- Do not add other `<style>` or `<link>` elements: the editor removes them when it saves (see [Inline Styles Only](https://envoke-developers.pages.dev/email-html/css-and-mobile/#inline-styles-only)).

---

## The Body Wrapper

```html
<body class="nvkbody" style="padding: 0px; margin: 0px; background-color: #f4f4f4; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 15px;">
<div class="nvkbody wrapper" style="width: 100%; background-color: #f4f4f4; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 15px;">
<center>
<table class="layout-table" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="center" valign="top">
<table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="680">
<tr>
<td align="center" valign="top">
  <!-- sections go here -->
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</div>
</body>
```

- `class="nvkbody"` on both `<body>` and the wrapper `<div>` is where the editor's message-wide style settings (background, text colour, font) read and write. Set your message's background colour, text colour, and font in both `style` attributes.
- The 680-pixel table sets the email's width; sections inside it are 660 pixels wide. These are the widths Envoke's own templates and footer use.
- Write `<body>` in lower case: Envoke inserts some content immediately after it (see [The Consent Banner](https://envoke-developers.pages.dev/email-html/unsubscribe-and-footer/#the-consent-banner)).

---

## Sections

A one-column section, with the same tables and classes the editor uses for the sections it creates:

```html
<div class="block-outer">
  <table class="layout-table outer-table" align="center" cellpadding="0" cellspacing="0" width="660">
    <tr>
      <td class="block-inner-background block layout-column outer-column" style="background-color: #ffffff; color: #333333;" align="center" valign="top">
        <table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="660">
          <tr>
            <td class="block-inner-background" style="background-color: #ffffff; color: #333333;" align="left" valign="top">
              <!-- rows go here -->
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</div>
```

- Copy the section as it is and change only the colours. The section's background colour goes on both cells marked `block-inner-background`.
- Every top-level section is a `div` with `class="block-outer"`, placed directly in the cell that holds the sections. Users add new sections between existing ones, so a template with no sections cannot have any added.
- The cell that directly holds the rows is where users drop new blocks.

---

## Rows and Regions

Each row is a `block-inner` holding one table, one cell, and one editable region:

```html
<div class="block-inner">
  <table class="inner-table" align="center" cellpadding="0" cellspacing="0" width="660">
    <tr>
      <td class="inner-column" style="padding: 15px 20px;" align="left" valign="top">
        <div class="content-edit" rel="#bck-overlay">
          <p>Your text here.</p>
        </div>
      </td>
    </tr>
  </table>
</div>
```

- **One editable region per row.** The editor edits a row as a single block, so a second `content-edit` in the same row can never be edited. A heading with a button below it is two rows: a text row and a button row.
- The `inner-table` is as wide as the column it sits in: 660 in a one-column section.
- Padding and the row's own background colour go on the `inner-column` cell.
- Copy the `rel` attribute as shown for each block type; it is part of the markup the editor itself writes.

The classes on the editable region decide what kind of block the row is, and so which settings the editor offers for it:

| Block | Editable region | Details |
|---|---|---|
| Text | `<div class="content-edit" rel="#bck-overlay">` | [Text](https://envoke-developers.pages.dev/email-html/blocks/#text) |
| Image | `<div class="content-edit image-edit" rel="#image-overlay">` | [Image](https://envoke-developers.pages.dev/email-html/blocks/#image) |
| Button | `<div class="content-edit cta-edit" rel="#cta-overlay">` | [Button](https://envoke-developers.pages.dev/email-html/blocks/#button) |
| Divider | `<div class="content-edit divider-edit" rel="#bck-overlay">` | [Divider](https://envoke-developers.pages.dev/email-html/blocks/#divider) |
| Video | `<div class="content-edit video-edit" rel="#video-overlay">` | [Video](https://envoke-developers.pages.dev/email-html/blocks/#video) |

---

## Columns

A section can be split into columns. Each column is a cell with its own rows, and every row's `inner-table` is as wide as its column.

| Layout | Column widths, left to right |
|---|---|
| Two columns | 330, 330 |
| Left sidebar | 200, 460 |
| Right sidebar | 460, 200 |
| Three columns | 220, 220, 220 |

The editor recognises the layout from the width of the first column, so use these widths exactly. A two-column section:

```html
<div class="block-outer">
  <table class="layout-table outer-table" align="center" cellpadding="0" cellspacing="0" width="660">
    <tr>
      <td class="block-inner-background block layout-column outer-column" style="background-color: #ffffff; color: #333333;" align="center" valign="top" width="330">
        <table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="330">
          <tr>
            <td class="block-inner-background" style="background-color: #ffffff; color: #333333;" align="left" valign="top">
              <!-- left column rows, each inner-table width="330" -->
            </td>
          </tr>
        </table>
      </td>
      <td class="block-inner-background block layout-column" style="background-color: #ffffff; color: #333333;" align="center" valign="top" width="330">
        <table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="330">
          <tr>
            <td class="block-inner-background" style="background-color: #ffffff; color: #333333;" align="left" valign="top">
              <!-- right column rows, each inner-table width="330" -->
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</div>
```

On phones, column cells with the `block` class stack one above the other at full width. The editor's section settings can turn this off, by removing the class.

---

## A Complete Template

A one-column email with a heading and text, an image, a button, and a footer with the unsubscribe link and postal address. Replace the image URL and link, then send it as `html` to the [Templates API](https://envoke-developers.pages.dev/v2/templates/insert/).

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="TEMPLATE_VERSION" content="230609">
<title>{@msg-subject}</title>
<style type="text/css" id="envoke-styles"> .inner-column { line-height: 1.3; } .image-edit { line-height: 0; } .image-edit.image-empty { display: none; } a { text-decoration: none; } u a { text-decoration: underline; } p, h1, h2, h3, h4, li { margin: 0; padding: 0; margin-bottom: 0; } h1, h2, h3, h4 { font-weight: normal; } ul, ol { margin-top: 0; margin-bottom: 0; } .desktop-hide { display:none !important; } @media screen and (max-width: 540px) { table { width:100% !important; } td.block { width:100% !important; display:block !important; } img.responsive-width { width:100% !important; height:auto !important; margin:0 !important; } table.nvkButtonTable { width: auto !important; } .mobile-hide { display:none !important; } .desktop-hide { display:block !important; } .block-inner .inner-column { padding-left: 20px !important; padding-right: 20px !important; } .block-inner .inner-column.mobile-full-width { padding-left: 0 !important; padding-right: 0 !important; } p, li, p span, li span { font-size:16px !important; } .column-table-rows .inner-column { height: auto !important; } } </style>
</head>
<body class="nvkbody" style="padding: 0px; margin: 0px; background-color: #f4f4f4; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 15px;">
<div class="nvkbody wrapper" style="width: 100%; background-color: #f4f4f4; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 15px;">
<center>
<table class="layout-table" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td id="preheader-text" style="display:none !important; visibility:hidden; mso-hide:all; font-size:1px; color:#ffffff; line-height:1px; max-height:0px; max-width:0px; opacity:0; overflow:hidden;">This month: new courses and early-bird pricing</td>
</tr>
<tr>
<td align="center" valign="top">
<table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="680">
<tr>
<td align="center" valign="top">

<div class="block-outer">
  <table class="layout-table outer-table" align="center" cellpadding="0" cellspacing="0" width="660">
    <tr>
      <td class="block-inner-background block layout-column outer-column" style="background-color: #ffffff; color: #333333;" align="center" valign="top">
        <table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="660">
          <tr>
            <td class="block-inner-background" style="background-color: #ffffff; color: #333333;" align="left" valign="top">

              <div class="block-inner">
                <table class="inner-table" align="center" cellpadding="0" cellspacing="0" width="660">
                  <tr>
                    <td class="inner-column" style="padding: 30px 20px 15px;" align="left" valign="top">
                      <div class="content-edit" rel="#bck-overlay">
                        <h1><span style="font-size: 32px; color: #1e3457;">Hello {fname},</span></h1>
                        <p>&nbsp;</p>
                        <p>Here is what is new this month.</p>
                      </div>
                    </td>
                  </tr>
                </table>
              </div>

              <div class="block-inner">
                <table class="inner-table" align="center" cellpadding="0" cellspacing="0" width="660">
                  <tr>
                    <td class="inner-column mobile-full-width" style="padding: 0px; text-align: center;" align="left" valign="top">
                      <div class="content-edit image-edit" style="text-align: center;" rel="#image-overlay">
                        <img src="https://www.example.com/images/spring-courses.jpg" width="660" style="width: 660px; height: auto;" alt="Students in the new studio" class="responsive-width">
                      </div>
                    </td>
                  </tr>
                </table>
              </div>

              <div class="block-inner">
                <table class="inner-table" align="center" cellpadding="0" cellspacing="0" width="660">
                  <tr>
                    <td class="inner-column" style="padding: 0px 20px;" align="left" valign="top">
                      <div class="content-edit cta-edit" style="text-align: center;" rel="#cta-overlay">
                        <table border="0" cellpadding="0" cellspacing="0" width="100%" class="nvkButtonContainer" style="min-width: 100%; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">
                          <tr>
                            <td class="nvkButtonContainerCell" style="padding-top: 10px; padding-bottom: 30px;" valign="top" align="center">
                              <table border="0" cellpadding="0" cellspacing="0" class="nvkButtonTable" style="border-collapse: separate !important; border-radius: 3px; background-color: #1e3457;">
                                <tr>
                                  <td align="center" valign="middle" class="nvkButtonTableCell" style="font-size: 16px; padding: 15px;">
                                    <a class="nvkButton " title="See the courses" href="https://www.example.com/courses" target="_blank" style="font-family: Arial, Helvetica, sans-serif; font-weight: normal; letter-spacing: normal; line-height: 100%; text-align: center; text-decoration: none; color: #ffffff; display: block;">See the courses</a>
                                  </td>
                                </tr>
                              </table>
                            </td>
                          </tr>
                        </table>
                      </div>
                    </td>
                  </tr>
                </table>
              </div>

            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</div>

<div class="block-outer">
  <table class="layout-table outer-table" align="center" cellpadding="0" cellspacing="0" width="660">
    <tr>
      <td class="block-inner-background block layout-column outer-column" style="background-color: #f4f4f4; color: #555555;" align="center" valign="top">
        <table class="layout-table" align="center" cellpadding="0" cellspacing="0" width="660">
          <tr>
            <td class="block-inner-background" style="background-color: #f4f4f4; color: #555555;" align="left" valign="top">

              <div class="block-inner">
                <table class="inner-table" align="center" cellpadding="0" cellspacing="0" width="660">
                  <tr>
                    <td class="inner-column" style="padding: 20px;" align="left" valign="top">
                      <div class="content-edit" rel="#bck-overlay">
                        <p style="text-align: center;"><span style="font-size: 13px;">{@brand-company}<br>{@brand-address}</span></p>
                        <p style="text-align: center;"><span style="font-size: 13px;"><u><a href="{@pref-0}">Update your email preferences or unsubscribe</a></u></span></p>
                      </div>
                    </td>
                  </tr>
                </table>
              </div>

            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</div>

</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
</div>
</body>
</html>
```

---

## The Preheader

The preheader is the short line inbox lists show after the subject. Envoke keeps it in a hidden cell with `id="preheader-text"`, as in the template above.

- When the message is opened in the drag-and-drop editor, the cell's text appears in the editor's **Preheader text** field, and saving writes the field back into the cell. If the cell is missing and the field is filled in, the editor adds the cell above the first table row.
- The preheader is plain text: write it as text in the cell, with no markup.
- Templates do not keep a preheader: saving a template in the editor empties the cell. Set the preheader on each message.
- The Messages and Send APIs have no preheader field; put the cell in your HTML instead.

---

## What the Editor Adds and Changes

You do not need to write the following; the editor adds or changes them every time a message is opened:

| On open | Effect |
|---|---|
| Envoke's style block | Replaced with the editor's current version |
| `<base target="_blank">` | Added if the head has no `<base>` element, so links open in a new tab |
| Font stylesheet | A Google Fonts link for the editor's font menu is added (see [Fonts](https://envoke-developers.pages.dev/email-html/css-and-mobile/#fonts)) |
| Drop zones | Classes marking where sections and rows can be dropped are added |
| Layout classes | Each section is classed as one-column, two-column, sidebar, or three-column from its column widths |
| Accessibility roles | `role="presentation"` on layout tables and `role="article"` on the wrapper `<div>` |
| Fonts on rows | Each row's `inner-column` cell is given an inline `font-family`, so Outlook does not fall back to Times New Roman |
| Small images | Images narrower than 270 pixels are set to keep their size on phones (see [Image Size on Phones](https://envoke-developers.pages.dev/email-html/blocks/#image-size-on-phones)) |
| Images that do not load | An image narrower than 60 pixels is widened to 60, and an image with no `alt` text is given the alt text ` BROKEN IMAGE (!) `, so the problem is visible. These changes are saved with the message. |

When the message is saved in the drag-and-drop editor, the whole document is rewritten:

| On save | Effect |
|---|---|
| Doctype and `<html>` | Replaced with the XHTML 1.0 Transitional doctype and `<HTML xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">`, whatever yours were. The language is changed at send for French messages (see [What Happens When Envoke Sends](https://envoke-developers.pages.dev/email-html/what-happens-at-send/#step-by-step)). |
| `<style>`, `<link>`, `<iframe>` | Removed, except Envoke's own style block and font link |
| `<script>` | Removed |
| `<tbody>` | Removed; the rows stay |
| Blank lines | Runs of line breaks become one |
| `%7B` and `%7D` | Turned back into `{` and `}` everywhere in the document, including inside URLs |
| `https://{@` | Becomes `{@`, so `href="https://{@msg-url}"` becomes `href="{@msg-url}"` |
| Images | Every image without the `actual-size` class is given `responsive-width`, so it scales down on phones |
| `Helvetica Neue` | Removed from every font list |
| `desktop-hide` | Content with this class is wrapped in comments that hide it from Outlook (see [Mobile Classes](https://envoke-developers.pages.dev/email-html/css-and-mobile/#mobile-classes)) |
| Preheader | Written from the editor's Preheader text field (see [The Preheader](#the-preheader)) |

Text in a block is also filtered when a user edits it; see [What Text Editing Keeps](https://envoke-developers.pages.dev/email-html/blocks/#what-text-editing-keeps).

---

## HTML Without Sections or Rows

HTML with the `TEMPLATE_VERSION` meta tag but none of the structure above still opens in the drag-and-drop editor, but nothing in it can be selected or edited, no sections or blocks can be added, and the editor's sidebar offers no new sections. The only way to change it is the [Edit HTML page](https://envoke-developers.pages.dev/email-html/getting-html-into-envoke/#edit-html-page).

A row (`block-inner`) placed directly in a cell without its `inner-table` and `inner-column` is rebuilt by the editor when the message is opened, with padding worked out from the surrounding widths. The result depends on the markup around it, so write the full row as shown above.

---

*Full reference, OpenAPI description, and Postman collection: [developers.envoke.com](https://developers.envoke.com).*
