Slack Channel
Norq compiles Slack templates from Markdown to Slack Block Kit JSON (Slack's native rich message format) with mrkdwn (Slack's markup syntax, similar to Markdown) formatting.
Pipeline: Markdown -> AST (parse tree) -> Block Kit JSON (blocks + fallback text)
Template files
slack.md-- Markdown mode (recommended)slack.json-- Native JSON mode (for advanced Block Kit features)
Use one or the other, never both.
Frontmatter
---
enabled: true
---| Field | Required | Description |
|---|---|---|
enabled |
No | true (default) or false. Disables the channel. |
Directive compilation
| Directive | Slack output |
|---|---|
:::header |
header block (plain_text, max 150 chars) |
:::footer |
context block (mrkdwn) |
:::action |
actions block with button elements (style=primary/danger) |
:::callout |
section block with :information_source: prefix |
:::hero |
Content rendered as normal blocks |
:::fields |
section block with fields array (mrkdwn: *Key:* Value) |
:::media |
image block for images; mrkdwn link for others |
:::columns |
section block with fields array (one field per column) |
:::list |
section block with list-formatted mrkdwn |
:::highlight |
section block with bold mrkdwn (*text*) |
:::centered |
Plain text (no alignment in Block Kit) |
:::raw |
Parsed JSON inserted as Block Kit block(s) |
Markdown mode example
::: header
Order Shipped
:::
Hey {{user.first_name}}, your order *#{{order.id}}* has shipped!
::: fields
Tracking ID: {{order.tracking_id}}
Delivery: {{order.delivery_date}}
:::
::: action
[Track Order]({{tracking_url}}){primary}
:::
::: footer
Order notification
:::Compiled output
Norq compiles the above template into Block Kit JSON:
{
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "Order Shipped" }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hey Gaurav, your order *#ORD-123* has shipped!"
}
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Tracking ID:* TRK-456" },
{ "type": "mrkdwn", "text": "*Delivery:* Mar 30" }
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "Track Order" },
"url": "https://track.example.com/123",
"style": "primary"
}
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "Order notification" }
]
}
],
"text": "Hey Gaurav, your order #ORD-123 has shipped!"
}The text field is a plain-text fallback for notifications and accessibility.
Highlight
Rendered as a section block with bold mrkdwn text.
::: highlight
New feature: dark mode is here!
:::Compiles to:
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*New feature: dark mode is here!*"
}
}Native JSON mode
For features not covered by directives (date pickers, static selects, overflow menus), use slack.json:
{
"$norq": { "enabled": true },
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hey *{{user.first_name}}*, your order has shipped."
},
"accessory": {
"type": "datepicker",
"initial_date": "{{order.delivery_date}}",
"placeholder": { "type": "plain_text", "text": "Delivery date" },
"action_id": "delivery-date"
}
}
],
"text": "Order {{order.id}} shipped"
}Inline formatting
Markdown inline formatting maps to Slack mrkdwn:
| Markdown | Slack mrkdwn |
|---|---|
**bold** |
*bold* |
*italic* |
_italic_ |
~~strikethrough~~ |
~strikethrough~ |
`code` |
`code` |
[text](url) |
<url|text> |
Testing
tests:
- name: "Slack has header block"
channel: slack
sample: "New user"
assert:
blocks: { any: { type: "header" } }
- name: "Slack has action button"
channel: slack
sample: "New user"
assert:
blocks: { any: { type: "actions" } }Best practices
- Slack header blocks have a 150-character limit -- keep header text short
- Slack supports max 10 fields per section block -- split large field sets
- Use
:::rawwith Block Kit JSON for interactive elements (menus, date pickers) - The
textfallback is auto-generated -- do not rely on it for critical content