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
Section titled “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
Section titled “The Head”<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_VERSIONmakes the HTML open in the drag-and-drop editor (see 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. 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).
The Body Wrapper
Section titled “The Body Wrapper”<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 bothstyleattributes.- 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).
Sections
Section titled “Sections”A one-column section, with the same tables and classes the editor uses for the sections it creates:
<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
divwithclass="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
Section titled “Rows and Regions”Each row is a block-inner holding one table, one cell, and one editable region:
<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-editin 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-tableis 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-columncell. - Copy the
relattribute 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 |
| Image | <div class="content-edit image-edit" rel="#image-overlay"> |
Image |
| Button | <div class="content-edit cta-edit" rel="#cta-overlay"> |
Button |
| Divider | <div class="content-edit divider-edit" rel="#bck-overlay"> |
Divider |
| Video | <div class="content-edit video-edit" rel="#video-overlay"> |
Video |
Columns
Section titled “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:
<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
Section titled “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.
<!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> </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
Section titled “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
Section titled “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) |
| 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) |
| 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). |
<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) |
| Preheader | Written from the editor’s Preheader text field (see The Preheader) |
Text in a block is also filtered when a user edits it; see What Text Editing Keeps.
HTML Without Sections or Rows
Section titled “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.
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.

