Directives

Directives use :::name ... ::: syntax to mark semantic regions of your template (similar to fenced code blocks in Markdown). Each directive compiles to the appropriate structure for each channel.

Norq has 16 directives: 12 content directives, 3 control flow directives, and :::table for iterable data tables.

Directive parameters

Content directives accept optional parameters after the name. These affect email rendering (other channels ignore them). Parameters are space-separated — order doesn't matter. Expressions like {{var}} are supported.

Parameter Syntax Effect
Alignment center, left, right Text alignment
Spacing compact, spacious Reduced or increased padding
Background bg=#hex Background color override
Text color color=#hex Text color override
Image URL bare URL or {{var}} Background image (hero only)

All content directives (header, footer, callout, highlight, fields, centered, hero) support all parameters. Expressions like {{variable}} are resolved in params.

Examples:

::: header center bg=#1e3a5f color=#ffffff
White text on dark header
:::
 
::: callout bg=#fff3cd color=#856d0e
Warning-styled callout
:::
 
::: footer right color=#999999
[Unsubscribe]({{unsubscribe_url}})
:::
 
::: hero {{hero_image_url}}
# Dynamic background image
:::

Content directives

Top section of the notification -- logos, brand name, title.

::: header
Order Shipped
:::
Channel Compilation target
Email Background-colored MJML section with text
SMS Ignored
Slack Block Kit header block (plain_text)
Push Title source (highest priority)
WhatsApp Bold text (*header text*)
Teams TextBlock with ExtraLarge + Bolder

Bottom section -- legal text, unsubscribe links, context.

::: footer
[Unsubscribe]({{unsubscribe_url}})
:::
Channel Compilation target
Email Small-font MJML section (12px, #666)
SMS Appended after newline
Slack Context block (mrkdwn)
Push Ignored
WhatsApp Footer text in interactive messages; ignored in text-only
Teams TextBlock with isSubtle=true, size=Small

:::table

Iterable data table — combines table rendering with array iteration. Header row renders once, template row repeats per item. Supports variable pipe arguments in cells.

::: table products as item
| Product | Qty | Subtotal |
|---------|-----|----------|
| {{item.name}} | {{item.qty}} | {{item.cost | multiply item.qty | currency "USD"}} |
:::
Channel Compilation target
Email HTML <table> with styled header and data rows
SMS Pipe-separated text (Product | Qty | Subtotal)
Slack Bold headers + pipe-separated rows in a section
Push Pipe-separated text
WhatsApp Pipe-separated text
Teams Adaptive Card FactSet

If the collection is empty, only the header row renders (empty table). The | inside {{ }} expressions is handled correctly — it won't break column separation.

:::action

CTA buttons. Contains Markdown links with style hints.

::: action
[Track Order]({{tracking_url}}){primary}
[Cancel Order]({{cancel_url}}){danger}
[View Details]({{details_url}}){secondary}
:::

Button styles: {primary}, {secondary}, {danger}.

Channel Compilation target
Email mj-button with href
SMS "Label: url" plain text
Slack Actions block with button elements (style=primary)
Push action_url extracted from first link
WhatsApp Reply buttons (max 3) in interactive mode; URL buttons in template mode
Teams Action.OpenUrl entries in card actions array

:::callout

Highlighted note or warning box.

::: callout
Your payment method will be charged within 24 hours.
:::
Channel Compilation target
Email Background-colored MJML section (#fff3cd)
SMS Rendered as plain text (no styling)
Slack Section block with :information_source: prefix
Push Body text with warning symbol prefix
WhatsApp Body text with warning symbol prefix
Teams Container with style=accent

:::hero

Full-width hero image.

::: hero
![Hero banner](https://cdn.example.com/hero.png)
:::
Channel Compilation target
Email Content rendered inline (images become mj-image)
SMS Ignored
Slack Content rendered as normal blocks
Push Image URL extracted for push image field
WhatsApp Image URL extracted; triggers image message type
Teams Image element with size=Stretch

:::fields

Key-value pairs, one per line. Useful for order details, invoice line items, etc.

::: fields
Order ID: {{order.id}}
Status: {{order.status}}
Total: {{order.total}}
:::
Channel Compilation target
Email HTML table with bold keys (font-weight:bold)
SMS Plain text lines ("Key: Value")
Slack Section block with fields array (mrkdwn: *Key:* Value)
Push Body text lines ("Key: Value")
WhatsApp Bold key formatting (*Key:* Value)
Teams FactSet with title/value facts

:::media

Embedded image, video, or file. Use the type parameter to specify the media type.

::: media type=image
![Product photo](https://cdn.example.com/product.jpg)
:::
 
::: media type=video
[Watch the demo](https://cdn.example.com/demo.mp4)
:::

Params: type=image (default), type=video, type=file.

Channel Compilation target
Email mj-image for images; link for other types
SMS URL as plain text; ignored for non-URL content
Slack Image block for images; mrkdwn link for others
Push Rendered as text (graceful degradation)
WhatsApp Ignored (hero/images handled separately)
Teams Image element; altText from alt attribute

:::columns

Multi-column layout with nested :::col blocks.

::: columns
::: col
**Shipping Address**
123 Main St
New York, NY 10001
:::
::: col
**Billing Address**
456 Oak Ave
San Francisco, CA 94102
:::
:::
Channel Compilation target
Email MJML native multi-column layout (mj-section > mj-column)
SMS Stacked sequentially as text
Slack Section block with fields array (one field per column)
Push Stacked as text (graceful degradation)
WhatsApp Stacked as text lines
Teams ColumnSet with Column elements (width=stretch)

:::list

Styled list.

::: list
- Choose your plan
- Add your team
- Start sending
:::
Channel Compilation target
Email HTML list inside mj-text
SMS Numbered lines
Slack Section block with list-formatted mrkdwn
Push Text lines
WhatsApp Text lines
Teams TextBlock with list text

:::raw

Raw channel-native code. An escape hatch for channel-specific features that directives don't cover.

::: raw
```html
<table style="width:100%">
  <tr><td>Custom HTML</td></tr>
</table>
```
:::

The content must be a fenced code block inside the directive.

Channel Compilation target
Email mj-raw passthrough (HTML inside code block)
SMS Ignored
Slack Parsed JSON inserted as Block Kit block(s)
Push Ignored
WhatsApp Ignored
Teams Parsed JSON inserted as Adaptive Card element

:::highlight

Dark card with prominent text. Use for announcements, special offers, or key information that must stand out.

::: highlight
Limited-time offer: 50% off all plans!
:::
Channel Compilation target
Email Dark mj-column (brandColor background, white text, 600 weight, 8px radius)
SMS Star prefix (⭐ text)
Slack section block with bold mrkdwn (*text*)
Push Star prefix (⭐ text)
WhatsApp Bold text (*text*)
Teams Container with style=attention and TextBlock

:::centered

Center-aligned text block. Use for taglines, thank-you messages, or any content that reads better centered.

::: centered
Thank you for being a customer.
:::
Channel Compilation target
Email mj-text with align="center"
SMS Plain text (no alignment in SMS)
Slack Plain text (no alignment in Slack)
Push Plain text (no alignment in push)
WhatsApp Plain text (no alignment in WhatsApp)
Teams Plain text (no alignment in Adaptive Cards)

Control flow directives

:::if / :::else

Conditional rendering. See the control flow page for full details.

::: if order.shipped
Your order has shipped!
:::else
Your order is being processed.
:::

:::each

Loop over an array. See the control flow page for full details.

::: each order.items as item
- {{item.name}} x {{item.qty}} -- ${{item.price}}
:::