Newsletter HTML Builder

Write your newsletter as one section per line and get a complete, responsive HTML email back — table-based layout, inline CSS, an Outlook ghost table, a hidden preheader and optional dark mode. Runs entirely in your browser, no server, no sign-up.

Try:
Email HTML

About this tool

Email clients are not browsers. Gmail strips <style> blocks in forwarded messages, Outlook renders with Word's layout engine, and flexbox or grid simply do not exist in most inboxes. This builder takes a plain list of sections and returns the markup those clients actually understand: nested role="presentation" tables, every declaration inlined on the element it styles, an Outlook ghost-table wrapper in a conditional comment, mso-table-lspace resets, and a single mobile media query that drops the fixed-width card to 100%.

You write content, not markup:

heading | What shipped in March
text | Hi {{first_name}}, three things went live this month.
columns | **Faster exports** — 4x quicker. | **New API keys** — scoped and revocable.
button | Read the release notes | https://example.com/changelog
divider
footer | [Unsubscribe]({{unsubscribe_url}})

Worked example

Input — one section, defaults everywhere else:

button | Read more | https://example.com

Output (the button row inside the generated document):

<tr>
  <td align="center" style="padding:24px 32px;">
    <table role="presentation" cellpadding="0" cellspacing="0" border="0">
      <tr>
        <td align="center" bgcolor="#2563eb" style="border-radius:6px;background-color:#2563eb;">
          <a href="https://example.com" style="display:inline-block;padding:14px 28px;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;font-size:16px;line-height:20px;color:#ffffff; font-weight:600;color:#ffffff;text-decoration:none;border-radius:6px;">Read more</a>
        </td>
      </tr>
    </table>
  </td>
</tr>

That is the "bulletproof button" pattern — a background-coloured table cell with a padded display:inline-block link inside it, so the whole rectangle stays clickable in clients that ignore padding on anchors, and it degrades to a plain coloured cell where border-radius is unsupported.

Section types

TypeLineNotes
headingheading | Big title28px, bold
subheadingsubheading | Smaller title20px, semi-bold
texttext | A paragraph16px/26px body copy
buttonbutton | Label | https://…bulletproof button, accent-coloured
imageimage | https://…png | Alt | https://…full-bleed, fluid; 4th part is an optional link
columnscolumns | Left | Righttwo 50% cells that stack on mobile
dividerdivider1px rule
spacerspacer | 24blank vertical space, px
footerfooter | Small print12px, muted, centred
htmlhtml | <p>…</p>raw markup, passed through verbatim

Inside any text you can use **bold**, *italic*, [label](https://example.com) and \n for a line break. Merge tags such as {{first_name}}, {{unsubscribe_url}} or *|FNAME|* pass through untouched, so the output can be pasted straight into Mailchimp, Klaviyo, Brevo, Postmark or your own sending code. Lines beginning with # are comments.

Limits and edge cases

FAQ

Why is all the CSS inline instead of a style block?

Because several clients delete <style> blocks. Gmail's web client strips them when a message is forwarded, and some corporate filters remove them outright. Anything that must survive — colours, fonts, padding, widths — is written on the element itself. The <style> block is used only for the things that cannot be inlined: the mobile media query and the dark-mode block. If both are stripped, the email still renders correctly at its fixed width.

Will this render correctly in Outlook?

Outlook on Windows renders with Word, which ignores max-width, border-radius and most modern CSS. The output handles that with a conditional-comment ghost table (<!--[if mso]>) that pins the content to a real fixed-width table, an o:PixelsPerInch setting so images are not scaled up, and mso-table-lspace/mso-table-rspace resets that remove Word's phantom table gutters. Buttons fall back to square corners there — that is expected, not a bug.

What is a preheader, and why is it padded with strange characters?

The preheader is the short line most inboxes show after the subject. It is rendered as a zero-height, transparent, mso-hide:all div at the top of the body. Without padding, the client would continue pulling in whatever comes next — usually "View in browser" or your first heading — and append it to the preview. The run of &#847;&zwnj;&nbsp;&#8199;&#65279; characters is invisible filler that consumes the rest of the preview slot.

How does the dark-mode option work?

With the box ticked, the document gets color-scheme / supported-color-schemes meta tags and a @media (prefers-color-scheme: dark) block that swaps the page, card, text, muted and rule colours for dark equivalents. Apple Mail, Outlook on macOS/iOS and several others honour it. Gmail and Outlook.com apply their own colour inversion regardless — the meta tags make that inversion less aggressive. Untick the box if you want the light palette everywhere.

Can I use merge tags and personalisation variables?

Yes. Text is escaped for HTML but {{first_name}}, *|FNAME|* and similar tags contain no HTML-special characters, so they survive verbatim. Merge tags are also accepted as URLs — for example [Unsubscribe]({{unsubscribe_url}}) — because most sending platforms substitute the real link at send time.

Do the two-column sections stack on phones?

Yes. The columns are 50%-width table cells carrying an sm-stack class; the media query switches them to display:block; width:100% below your chosen content width. Clients that drop the media query (older Gmail app versions on some Android builds) show them side by side, which is why each column is kept narrow enough to remain readable at half width.

How do I preview the result before sending?

Copy the output, save it as a .html file and open it in a browser for the layout, then send yourself a real test message through your sending platform — a browser cannot reproduce Outlook's Word engine or Gmail's CSS stripping. Sending one test to a Gmail address, one to Outlook and one to Apple Mail covers most of the market.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool newsletter-html-builder "heading | Product update
text | Hi {{first_name}}, here is what shipped this month.
button | Read the notes | https://example.com/changelog
divider
footer | [Unsubscribe](https://example.com/u)"

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/newsletter-html-builder/?sections=heading%20%7C%20Product%20update%0Atext%20%7C%20Hi%20%7B%7Bfirst_name%7D%7D%2C%20here%20is%20what%20shipped%20this%20month.%0Abutton%20%7C%20Read%20the%20notes%20%7C%20https%3A%2F%2Fexample.com%2Fchangelog%0Adivider%0Afooter%20%7C%20%5BUnsubscribe%5D%28https%3A%2F%2Fexample.com%2Fu%29&subject=March%20newsletter&preheader=Three%20new%20features%20and%20a%20discount%20inside&width=600&background=%23f4f4f5&content_background=%23ffffff&text_color=%231f2937&accent=%232563eb&font=system&dark_mode=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.