Code Block
Code people read or copy: an API request, a webhook's payload, a config file, a log excerpt, an embed snippet. A <pre><code> in a frame, with a title and a copy button. Specification: docs/components/code-block.md
Basics
A .canon-code-block around a <pre><code>. A .canon-code-block-header first holds a .canon-code-block-title (a file name, or what the code is) and its buttons: usually a Button with command="--canon-copy", whose commandfor names the <code>. It copies the code's text, without the highlighting.
{
"id": "evt_1Q2w3E",
"type": "invoice.paid",
"created": "2026-10-16T09:24:11Z",
"data": {
"invoice": "INV-2041",
"amount": 129000,
"currency": "EUR",
"paid": true,
"coupon": null
}
}
Without a header
For a short snippet, leave out the header: the copy button goes after the <pre>, and sits in the code's top corner. It is the right corner in every language, where lines end, since code reads left to right.
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
Highlighting
Canon doesn't highlight code; do it before the page is sent (on the server or at build time) and put the result inside the <code>. Themes color tokens by twinkleplop's names: <span class="tok string">, tok keyword, tok tag_name and so on. Code without tokens is plain text, which suits logs and keys.
These docs use twinkleplop for their own code: the examples on this page were highlighted ahead of time, and the Playground's HTML and the code in these notes are highlighted in the browser with @twinkleplop/html. Any highlighter works, as long as its tokens get those class names.
<script src="https://cdn.example.com/widget.js" defer></script>
<div class="support-widget" data-team="billing"></div>
sk_live_51Mx0Lq2eZvKYlo2C8f3Hj7Wn4rTb9QpXa6Yd
Long code
Code keeps its lines and scrolls in its box, sideways and, with --canon-code-block-max-height, down. A box that scrolls becomes a region named by the title (or "Code"), so keyboards can reach and scroll it.
# Billing worker, production
service: billing-worker
image: registry.example.com/billing-worker:2.14.0
replicas: 3
resources:
cpu: 500m
memory: 512Mi
env:
- name: QUEUE_URL
value: amqps://queue.internal:5671/billing
- name: RETRY_LIMIT
value: "5"
- name: LOG_LEVEL
value: info
healthcheck:
path: /healthz
interval: 10s
timeout: 2s
schedule:
- cron: "0 3 * * *"
task: reconcile-payouts
- cron: "*/15 * * * *"
task: retry-failed-charges
Wrapping
Long lines scroll by default, so columns stay aligned. A wrap button in the header, before the copy button, lets people wrap them instead: a Button with command="--canon-wrap", named "Wrap lines", whose aria-pressed is the state. Start it pressed (aria-pressed="true") where wrapped reads better, as for logs on a narrow screen.
2026-10-16 09:24:11.482 INFO [billing-worker-3] invoice.paid INV-2041 amount=1290.00 EUR customer=cus_8XkP2 attempt=1 latency_ms=184 trace=4bf92f3577b34da6a3ce929d0e0e4736
2026-10-16 09:24:12.007 WARN [billing-worker-1] charge.retry INV-2038 reason=card_declined decline_code=insufficient_funds attempt=3 next_retry=2026-10-16T09:39:12Z
2026-10-16 09:24:12.311 INFO [billing-worker-3] payout.created po_3Ld81 amount=48210.55 EUR destination=acct_1Mx0 arrival=2026-10-18
2026-10-16 09:24:11.482 INFO [billing-worker-3] invoice.paid INV-2041 amount=1290.00 EUR customer=cus_8XkP2 attempt=1 latency_ms=184 trace=4bf92f3577b34da6a3ce929d0e0e4736
2026-10-16 09:24:12.007 WARN [billing-worker-1] charge.retry INV-2038 reason=card_declined decline_code=insufficient_funds attempt=3 next_retry=2026-10-16T09:39:12Z
2026-10-16 09:24:12.311 INFO [billing-worker-3] payout.created po_3Ld81 amount=48210.55 EUR destination=acct_1Mx0 arrival=2026-10-18
Size
data-size on the block or a container sets the code's type and spacing. Its buttons take the size they're given.
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
Edge cases
A long title is cut (…). In right-to-left pages the header follows the page while the code stays left to right.
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"
curl https://api.example.com/v1/invoices/INV-2041 \
-H "Authorization: Bearer $API_TOKEN"