TRMNL Content Generator
Generate HTML content for TRMNL e-ink display devices.
Prerequisites
Install the trmnl
CLI to the latest version:
npm install -g trmnl-cli@latest
Configure a webhook plugin (one-time setup):
# Add a plugin
trmnl plugin add home "https://trmnl.com/api/custom_plugins/{uuid}"
Verify it's configured
trmnl plugin
Quick Start Workflow
- Install/update CLI: Run
npm install -g trmnl-cli@latest
- Check plugins: Run
trmnl plugin
- if none, prompt user to add one
- Confirm device type (default: TRMNL OG, 2-bit, 800x480)
- Read relevant reference docs based on content needs
- Generate HTML using TRMNL framework classes
- Write HTML to a temp file and send:
trmnl send --file /tmp/trmnl-content.html
# Or to a specific plugin:
trmnl send --file /tmp/trmnl-content.html --plugin office
- Minimal confirmation only - Do NOT echo content back to chat
Sending Content
From file (recommended):
# Write HTML content to file first
cat > /tmp/trmnl-content.html << 'EOF'
<div class="layout layout--col gap--space-between">
<div class="item">
<span class="value value--xlarge value--tnums">Hello TRMNL!</span>
</div>
</div>
<div class="title_bar">
<span class="title">My Plugin</span>
</div>
EOF
Send to display
trmnl send --file /tmp/trmnl-content.html
Validate before sending:
trmnl validate --file /tmp/trmnl-content.html
View send history:
trmnl history
trmnl history --today
trmnl history --failed
Webhook Limits
| Tier | Payload Size | Rate Limit |
|---|
| Free | 2 KB (2,048 bytes) | 12 requests/hour |
| TRMNL+ | 5 KB (5,120 bytes) | 30 requests/hour |
Set tier globally for accurate validation:
trmnl tier plus # or "free"
Reference Documentation
Read these files as needed:
| File | When to Read |
|---|
references/patterns.md
| Start here - Common plugin patterns |
references/framework-overview.md
| Device specs, e-ink constraints |
references/css-utilities.md
| Colors, typography, sizing, spacing |
references/layout-systems.md
| Flexbox, grid, overflow engines |
references/components.md
| Title bar, dividers, items, tables |
references/webhook-api.md
| Payload format, troubleshooting |
assets/anti-patterns.md
| Common mistakes to avoid |
Standard Plugin Structure
Every plugin follows this pattern:
<div class="layout layout--col gap--space-between">
<!-- Content sections separated by dividers -->
</div>
<div class="title_bar">
<img class="image" src="icon.svg">
<span class="title">Plugin Name</span>
<span class="instance">Context</span>
</div>
layout
+ layout--col
= vertical flex container
gap--space-between
= push sections to edges
title_bar
= always at bottom, outside layout
divider
= separate major sections
- CRITICAL: Only ONE
.layout
element per view
Quick Reference
Grid System (10-Column)
<div class="grid">
<div class="col--span-3">30%</div>
<div class="col--span-7">70%</div>
</div>
Item Component
<div class="item">
<div class="content">
<span class="value value--xlarge value--tnums">$159,022</span>
<span class="label">Total Sales</span>
</div>
</div>
Value Typography
Always use value--tnums
for numbers.
| Class | Usage |
|---|
value--xxxlarge
| Hero KPIs |
value--xxlarge
| Large prices |
value--xlarge
| Secondary metrics |
value--tnums
| Required for numbers |
Grayscale Classes
Use dithered classes, not inline colors:
bg--black
, bg--gray-60
, bg--gray-30
, bg--gray-10
, bg--white
text--black
, text--gray-50
Data Attributes
| Attribute | Purpose |
|---|
data-fit-value="true"
| Auto-resize text to fit |
data-clamp="N"
| Limit to N lines |
data-overflow="true"
| Enable overflow management |
Best Practices
- Use
layout
+ title_bar
structure
- Always
value--tnums
for numbers
- Use
data-fit-value
on primary metrics
- Use
bg--gray-*
dithered classes
- Keep payload under tier limit
- Minimal confirmations - just "Sent to TRMNL"
Troubleshooting
| Problem | Solution |
|---|
trmnl: command not found
| Run npm install -g trmnl-cli@latest
|
| No plugins configured | Run trmnl plugin add <name> <url>
|
| Webhook fails | trmnl config - verify plugin URL |
| Payload too large | trmnl validate --file - check size |
| Numbers misaligned | Add value--tnums class |
| Send history | trmnl history --failed
|