Actions and spans
Two inline components make an email actionable: :button for the one thing the reader should do, and :link for everything else. Spans style a run of text with a small, fixed set of classes.
::actions
:button[View payout]{href="{{payout_url}}"} :link[See orders]{href="{{orders_url}}"}
::
Add the primary button
:button[Label]{href="…"} renders a filled pill in the action colour, with a VML fallback so it stays a button in Outlook for Windows.
- One per template. A second
:buttonanywhere ismore than one :button in the template. An email with two primary actions has none; make the others:link. - Only in an action row of a
statementor anactionsmodule. In a letter it isletter: :button is not allowed; use :link. - On its own. A
:buttonin a paragraph with other text is:button must stand alone in its paragraph.
Add a text link
:link[Label]{href="…"} is a text link. How it renders depends on where it is:
- In an action row, it is a bold link in the action colour with
›appended, unless the label already ends with›. - In running text, it is an ordinary underlined link with no arrow — the same as
[Label](…).
We're lowering commission on services, as :link[the policy]{href="https://example.com/policies/fees"} explains.
:link[Read the full policy]{href="https://example.com/policies/fees"}
The first :link is inline; the second is alone in its paragraph, so it forms an action row and renders as "Read the full policy ›".
Write the label and href
Both components take exactly one attribute, href, and a label:
| Rule | Applies to | Error |
|---|---|---|
href is required and not empty. | every :button and :link | :link: missing href |
| No other attributes. | every :button and :link | :button: unknown attribute "target" |
| The label is required. | actions in an action row | :button: missing label |
| The label is plain text and merge tags only — no emphasis, code or links. | actions in an action row | :link: label must be plain text |
A :link inside running text is an ordinary link, so its label is inline Markdown like any link text (:link[**bold**]{href="…"} compiles), and an empty label is not checked.
href is text, so it can hold merge tags; how their values are escaped is in Know how URLs are escaped. At render time every URL must use https, http, mailto or tel, with a host (or an address), and no whitespace; anything else is a render error. Relative URLs are allowed only when Config.AllowRelativeURLs is set, for previews.
Build an action row
A paragraph made only of :button and :link components, separated by spaces or line breaks, is an action row. Its actions sit side by side; in a statement or actions module they stack, full width, on mobile.
| Where | Allowed actions |
|---|---|
statement | :button and :link |
actions (c1–c3) | :button and :link; the module is exactly one row |
letter, including loose Markdown | :link only |
| any other module | none (notice: action row is not allowed here) |
In the plain-text part, each action becomes its label with a colon, then its URL on the next line:
Track delivery:
https://caribhubs.com/orders/CH-20417
Link in running text
Inside paragraphs, list items, table cells and notices, use ordinary Markdown links:
If you keep getting these, [secure your account]({{security_url}}).
Write to <help@example.com> or see <https://example.com/help>.
[text](url)— the destination can hold merge tags. A link title ([text](url "title")) islink titles are not supported.<https://…>— an autolink shows the address as its text.<name@example.com>— an email autolink becomes amailto:link.:link[text]{href="…"}in a sentence is the same as[text](…).
In the plain-text part a link is written text (url), or just the URL when the text is the URL, or just the address for an email autolink.
Style text with spans
[text]{.class …} wraps inline Markdown in a style. The classes combine:
| Class | Effect |
|---|---|
.muted | The secondary text colour. |
.teal | The action colour. Wins over .muted if both are set. |
.mono | The theme's monospace font. |
.small | Smaller type: 13px on an 18px line. |
.bold | Bold weight. |
::breakdown
| Delivery fee | [**{{fee}}**]{.teal} |
| --- | ---: |
| [Payment]{.small .muted} | [Buyer paid in app]{.small .muted} |
::
Any other class is a compile error, unknown span class ".red", and a span accepts no #id or key=value (span: unknown attribute "#id"). The styles apply to the HTML part only; the plain-text part shows the text.
Spans are the only place a class may go. {.small} directly after a code span, a link or emphasis is attributes are only allowed on spans and inline components, so wrap the element in a span: [`{{reference}}`]{.small .muted}.
Next steps
- Modules for the modules that hold action rows.
- Compile errors for the full list of messages.