Email components
Write content in ordinary HTML and use email components only where a client needs table layout, button fallbacks, or required alt text.
Import Email, Section, Columns, Column, Button, Spacer, Divider, Image, Link,
IssueContent, IssueTitle and IssueDate from @samva/markup/email.
Write content in ordinary HTML: headings, paragraphs, lists, links, and tables. Components exist for email-client layout and the issue slots:
| Component | Why it exists |
|---|---|
Email | The document shell: <head>, reset styles, dark-mode meta, and the preheader slot |
Section | A full-width band, emitted as a table so Outlook keeps it |
Columns, Column | Side-by-side layout as table cells, stacking on mobile |
Button | A link styled as a button, with an Outlook fallback shape |
Image | Required alt, fixed dimensions, and a dark-mode source |
Spacer, Divider | Vertical rhythm and rules that survive clients that strip margins |
Link | A text link that opens outside the client |
IssueContent | The slot where a Markdown issue supplies the layout's content |
IssueTitle, IssueDate | The issue's frontmatter title and date, as text in an issue layout |
The brand components BrandLogo and BrandFooter come from samva:brand; see
Brands.
- A
Buttonneeds a string label and aheightfor the classic Outlook fallback. Without them the check warns withbutton-outlook-fallback. - Scripts, event handlers, and unsafe URL schemes are rejected. Strings are escaped text, never markup.
- General flex and grid layouts are not converted to email tables. Use
Columnsfor side-by-side content. subjectandpreheaderlive on theemailchannel of the definition.<Email>does not take apreheader.
See Authoring in TSX for a complete template.
Issue content slot
An issue layout is an email-only defineTemplate with one <IssueContent /> from
@samva/markup/email. Place it where the compiled Markdown body belongs. It takes no props or
children and must appear unconditionally, outside loops and conditions. Compiling the layout as an
issue replaces the slot with that issue's content; it is not an ordinary content component.
<IssueTitle /> and <IssueDate /> print the issue's frontmatter title and date as text, under
the same placement rules. IssueDate formats the YYYY-MM-DD date at compile time like fmt.date
(Oct 28, 2026 by default, in UTC); literal style and locale props change that. An issue without
a date prints nothing.
import { defineTemplate } from "@samva/markup";
import { Email, IssueContent, IssueDate, IssueTitle, Section } from "@samva/markup/email";
import { jsonSchema } from "@samva/markup/input-schema";
export default defineTemplate({
id: "newsletter-layout",
schema: jsonSchema({ type: "object", properties: {}, additionalProperties: false }),
fixtures: { default: {} },
email: {
subject: () => "Newsletter",
body: () => (
<Email>
<Section>
<h1><IssueTitle /></h1>
<p><IssueDate /></p>
<IssueContent />
</Section>
</Email>
),
},
});Preview · Available to selected organizations.
Author and send newsletter issues describes creating Markdown, previewing it in a layout, and saving the commit a campaign sends.