On this page

Wire ships layout components as markdown shortcodes. They render to styled HTML using Wire's built-in CSS and respect your theme colors automatically.

For the design rationale behind each component (border radius, hover states, color choices), see the Design System reference.

Stats

Display exactly 4 key metrics in a row. Each line: value | label. Desktop renders 4 across, mobile renders 2+2. The build linter (RULE-63) enforces exactly 4 items: other counts create orphan rows on mobile.

:::stats
300+ | Vendors Compared
24 | Capability Categories
715 | Side-by-Side Comparisons
108 | Expert Guides
:::
300+Vendors Compared
24Capability Categories
715Side-by-Side Comparisons
108Expert Guides

Cards

Grid of cards, split by ### headings. Include a link to make the whole card clickable. The CSS grid uses auto-fit so any number of cards wraps gracefully across rows.

:::cards
### OCR and Data Capture
Compare vendors specializing in optical character recognition and document data extraction.
[Browse OCR vendors](/your-topic/ocr/)

### AI and ML Platforms
Full-stack intelligent document processing with machine learning pipelines.
[Browse AI platforms](/your-topic/ai/)

### Cloud Solutions
Managed IDP services with API-first architecture and pay-per-page pricing.
[Browse cloud vendors](/your-topic/cloud/)
:::

Recent Articles

Auto-populated grid of the N most recently created articles. Each card shows the article title, creation date, description, and a short_title → link. Sorted newest first. Reuses the same .feature-card CSS as :::cards with no extra layout rules.

:::recent 6

:::

The argument is the number of articles to display. Default is 3 if omitted.

Wire populates the cards at build time from all article pages that have a created date. Topic index pages and pages without created are excluded. Use this on landing pages and category index pages to keep a live feed of new content without manually maintaining card lists.

Split

Two columns separated by ---. Markdown works inside both columns.

:::split
### Before Wire

- Raw HTML divs in every markdown file
- Custom CSS per client
- Different class names for the same component
- MkDocs extensions as hard dependency

---

### After Wire

- Clean shortcode syntax
- Built-in styled components
- Same syntax across all sites
- Zero dependencies on MkDocs
:::

Before Wire

  • Raw HTML divs in every markdown file
  • Custom CSS per client
  • Different class names for the same component
  • MkDocs extensions as hard dependency

After Wire

  • Clean shortcode syntax
  • Built-in styled components
  • Same syntax across all sites
  • Zero dependencies on MkDocs

Comparison variant

Add comparison after :::split to highlight the second column. Use for before/after or old-vs-new comparisons. The second column gets a primary-colored border, accent background, and top bar.

:::split comparison
### Traditional Approach

- Manual keyword research
- One-time audits
- Static content plans

---

### Wire Approach

- Automated GSC analysis
- Continuous refinement
- Data-driven content pipeline
:::

Traditional Approach

  • Manual keyword research
  • One-time audits
  • Static content plans

Wire Approach

  • Automated GSC analysis
  • Continuous refinement
  • Data-driven content pipeline

Big number callout. The value goes after :::banner, the explanation is the body. The value must be 6 characters or fewer. Longer values break the layout, and the build will refuse.

:::banner 223%
Companies using structured content strategies see 223% higher ROI on their marketing spend.
:::

Progress Bars

Horizontal bar chart for comparing values. Each line: label | value%. The linter (RULE-68) enforces values stay within 0-100%. Wire refuses the build if :::progress renders zero bars (empty body, or lines without |) or if multiple entries share one line (A: 1 | B: 2 | C: 3). That single-line pattern silently produced one nonsense bar before #395.

:::progress
Content-Engagement | 34%
Webinar-Einladung | 31%
Gemeinsamer Kontakt | 28%
:::
Content-Engagement34%
Webinar-Einladung31%
Gemeinsamer Kontakt28%

CTA Buttons

Button group from markdown links. Add {primary} for the primary action.

:::cta
[Get started](/guides/getting-started/){primary}
[View Pricing](/guides/pricing-comparison/)
:::

Badges

Inline tag list for capabilities, features, or certifications. Pipe-separated.

:::badges
On-Premise | Kubernetes | OCR | ISO 27.001 | API | RAG
:::
On-PremiseKubernetesOCRISO 27.001APIRAG

Badges use your theme's primary color and wrap naturally on narrow screens.

Tabs

Tabbed content panels. Split by ### headings; first tab is active by default.

:::tabs
### Banking & Finance
Automated invoice processing, compliance document handling, and financial statement analysis.

### Healthcare
Patient record digitization, claims processing, and medical document classification.

### Insurance
Policy document extraction, damage assessment automation, and underwriting workflows.
:::

Automated invoice processing, compliance document handling, and financial statement analysis.

Patient record digitization, claims processing, and medical document classification.

Policy document extraction, damage assessment automation, and underwriting workflows.

FAQ

Collapsible accordion using native <details>. Split by ### headings; question as summary, answer as body.

:::faq
### How does Wire handle SEO?
Wire audits your content against Google Search Console data, detects keyword cannibalization, and rewrites titles and descriptions automatically.

### Can I use my own templates?
Yes. Place template files in your templates/ directory and Wire will use them instead of the defaults.

### What about existing MkDocs sites?
Wire detects MkDocs extension syntax and refuses to build until you migrate to Wire shortcodes. The build error tells you exactly what to replace.
:::
How does Wire handle SEO?

Wire audits your content against Google Search Console data, detects keyword cannibalization, and rewrites titles and descriptions automatically.

Can I use my own templates?

Yes. Place template files in your templates/ directory and Wire will use them instead of the defaults.

What about existing MkDocs sites?

Wire detects MkDocs extension syntax and refuses to build until you migrate to Wire shortcodes. The build error tells you exactly what to replace.

Testimonials

Customer quotes with attribution.

:::testimonial
Wire replaced our entire MkDocs workflow. We went from spending 2 hours per page on SEO to minutes.
— Content Team Lead
:::

Wire replaced our entire MkDocs workflow. We went from spending 2 hours per page on SEO to minutes.

Content Team Lead

Logo Cloud

Display partner or client logos in a centered row. Logos appear greyscale and colorize on hover.

:::logos
![Partner A](/assets/img/logo-a.png)
![Partner B](/assets/img/logo-b.png)
:::

Pricing Table

Side-by-side pricing plans. Mark the featured plan with {primary}.

:::pricing
### Starter
$29/mo
For small teams getting started.
- 10 pages
- Basic SEO
- Email support
[Get started](/signup/)

### Pro
$99/mo
For growing content operations.
- 100 pages
- Full SEO suite
- Priority support
[Get started](/signup/){primary}

### Enterprise
Custom
For large-scale deployments.
- Unlimited pages
- Dedicated support
[Contact sales](/contact/)
:::

Starter

$29/mo

For small teams getting started.

  • 10 pages
  • Basic SEO
  • Email support
Get started

Enterprise

Custom

For large-scale deployments.

  • Unlimited pages
  • Dedicated support
Get started

Steps

Horizontal numbered steps for workflows or processes. Split by ### headings (3-4 steps max).

:::steps
### Create
Write content from search gaps and client questions.

### Optimize
Reword titles and headings to match real search queries.

### Publish
Build to static HTML with 91-rule linting.
:::
1

Create

Write content from search gaps and client questions.

2

Optimize

Reword titles and headings to match real search queries.

3

Publish

Build to static HTML with 91-rule linting.

Alerts

Callout boxes for info, success, warning, or error messages. Level goes after :::alert (default: info).

:::alert info
Info — default informational callout.
:::

:::alert success
Success — operation completed.
:::

:::alert warning
Warning — proceed with caution.
:::

:::alert error
Error — something went wrong.
:::

Info: default informational callout.

Success: operation completed.

Warning: proceed with caution.

Error: something went wrong.

Horizontal Rules

Standard markdown --- renders a clean divider:

Content above.

---

Content below.

Content above the divider.


Content below the divider.

Visual Breaks

Inline brand cards that break up long text walls. Pure HTML/CSS, no images generated, fully indexable by Google. Uses the customer's color scheme automatically.

:::visual Methodik
Datengetrieben, nicht raten
- Echte GSC-Daten statt Bauchgefühl
- Jede Empfehlung ist messbar
- Keine Vermutungen, nur Fakten
:::
Wire
Methodik

Datengetrieben, nicht raten

  • Echte GSC-Daten statt Bauchgefühl
  • Jede Empfehlung ist messbar
  • Keine Vermutungen, nur Fakten

The label (after :::visual) becomes a small uppercase tag. The first line of the body is the title. Remaining lines are the description.

Wire selects a subtle background pattern (dots, diagonal lines, or grid) deterministically from the label text. Same label always produces the same pattern. All patterns use var(--primary) at low opacity, so they match any customer's brand colors.

Section Bands

Wrap content in a full-width light background band.

:::section light
## Section Heading
Content inside the band.
:::

On landing pages (layout: landing), use --- (horizontal rules) instead. Wire automatically creates alternating section bands with a hero at the top. Customers own their own dark styling via custom CSS.

YouTube Embeds

Privacy-safe video embeds. No YouTube tracking loads until the user clicks play.

!yt[dQw4w9WgXcQ]
Video thumbnailClick to load video from YouTube

Wire downloads the thumbnail locally during build (stored in assets/yt/) so no request goes to YouTube until the visitor clicks play. This makes embeds GDPR-compliant by default.

Do not use raw iframes. The build linter (RULE-51) will reject <iframe src="youtube.com/...">. Use the !yt[] shortcode instead.

AI-Generated Images

Insert images generated by BFL (FLUX) using a descriptive slug. Images are generated once via the CLI and stored as normal project files.

!makeIMG[invoice-processing-pipeline]
!makeIMG[vendor-comparison-table]{wide}
!makeIMG[app-icon]{square}

The slug is both the prompt (hyphens become spaces) and the filename (docs/assets/images/{slug}.png).

Dimension Presets

Preset Syntax Size
Default !makeIMG[slug] 1024x576
Wide !makeIMG[slug]{wide} 1440x480
Square !makeIMG[slug]{square} 512x512

Configuration

Required in wire.yml. Using !makeIMG without this is a build error:

extra:
  wire:
    image_style: "Clean, modern flat illustration. Color palette: #6200ea primary, #ffc107 accent. White background, minimal detail, professional tone."

The style prompt is prepended to every slug so all images on your site share a consistent visual identity. Optional settings:

    image_model: flux-pro-1.1           # default
    image_sizes:                         # override dimensions
      default: [1024, 576]
      wide: [1440, 480]
      square: [512, 512]

Required in .env: BFL_API_KEY (get yours at api.bfl.ai).

Generating Images

python -m wire.chief images              # Generate missing images
python -m wire.chief images --dry-run    # Show what's missing + cost estimate
python -m wire.chief images --force      # Regenerate all
python -m wire.chief images --prune      # Remove orphan images

Missing images at build time are a build error. Wire refuses to build until you run wire.chief images.

Writing Good Slugs

Quality Slug Why
Good document-scanning-office-modern Concrete scene, visual
Good vendor-comparison-table-with-scores Specific, descriptive
Bad comparison Too vague. AI generates something generic
Bad abstract-concept-of-innovation Abstract concepts make ugly images

Forms

Wire styles all standard form elements out of the box. Write plain HTML forms in your markdown, no custom CSS classes needed.

<form>
  <label for="name">Name</label>
  <input type="text" id="name" placeholder="Your name">
  <label for="email">Email</label>
  <input type="email" id="email" placeholder="you@company.com">
  <label for="topic">Topic</label>
  <select id="topic">
    <option value="">Select a topic</option>
    <option value="seo">SEO</option>
    <option value="content">Content Strategy</option>
    <option value="other">Other</option>
  </select>
  <label for="message">Message</label>
  <textarea id="message" rows="4" placeholder="How can we help?"></textarea>
  <label><input type="checkbox" name="consent"> I agree to be contacted</label>
  <button type="submit">Send Message</button>
</form>

Wire styles inputs, textareas, selects, checkboxes, and submit buttons using your theme colors.

Structured Forms

For more control, use Wire's class-based form components:

<form class="wire-form">
  <div class="wire-form-row">
    <div class="wire-form-field">
      <label>Name</label>
      <input type="text" name="name">
    </div>
    <div class="wire-form-field">
      <label>Email</label>
      <input type="email" name="email">
    </div>
  </div>
  <div class="wire-form-field">
    <label>Interest</label>
    <div class="wire-form-checks">
      <label class="wire-check"><input type="checkbox" name="interest" value="SEO"> SEO</label>
      <label class="wire-check"><input type="checkbox" name="interest" value="Content"> Content</label>
    </div>
  </div>
  <button type="submit" class="wire-form-submit">Send</button>
  <p class="wire-form-note">No obligation.</p>
</form>
Class Purpose
.wire-form Form container (max-width 640px)
.wire-form-row Two-column grid (stacks on mobile)
.wire-form-field Field wrapper with label + input spacing
.wire-form-checks Flex container for checkbox pills
.wire-check Checkbox pill with checked state highlight
.wire-form-submit Submit button (uses --primary)
.wire-form-note Small text below submit
.wire-form-success Success message with accent bar

Selects get a custom dropdown arrow automatically. All colors use your theme's --primary and --accent.

Form Submission

Wire handles form submission automatically via Formspark. Add three values to wire.yml and every <form> on your site just works, no JavaScript in your markdown:

extra:
  wire:
    form_id: "your-formspark-id"
    form_botpoison: "pk_your-botpoison-public-key"
    form_success: "Thank you! We'll be in touch within 48 hours."
Setting What it does
form_id Formspark form ID. Submissions go to submit-form.com/{id}
form_botpoison Botpoison public key (pk_...) for invisible bot detection (optional). BUILD REFUSED if set to a secret key (sk_...). Secret keys must never be exposed client-side.
form_success Message shown after successful submit (optional)

Wire automatically adds:

  • Honeypot field (_gotcha): hidden spam trap that bots fill
  • Page source (wire_source): tracks which URL the form was submitted from
  • Bot verification (_botpoison): if key is configured, loads Botpoison and attaches solution token
  • Visited pages (wire_visited): the visitor's browsing journey before submitting

Lead Intelligence

Wire tracks which pages the visitor browses on every page (stored in localStorage, never sent to a server until form submit). When the visitor submits any form, the full journey is attached as a hidden wire_visited field:

1. [14:32] /
2. [14:33] /capabilities/seo-automation/
3. [14:35] /guides/pricing-comparison/
4. [14:36] /kontakt/

This tells you what the lead was researching before contacting you. No analytics tool needed, no cookies, no GDPR consent required (localStorage is not persistent and never leaves the browser until form submit).

Page tracking runs on ALL pages, even without form_id. This means the journey is recorded from the visitor's first page, not just from when they reach the form. Custom forms with their own action= attribute also receive the wire_visited hidden field automatically, with no configuration needed.

RULE-66 warns if a page has a <form> without an action= attribute and no form_id configured. This catches dead forms that render but cannot submit.

Configure the site footer in wire.yml. No footer config = minimal copyright line.

footer:
  tagline: "Your company tagline."
  email: info@example.com
  phone: +49 123 456 789
  links:
    Expertise:
      - SEO: /seo/
      - Content: /content/
    Company:
      - Team: /team/
      - Contact: /contact/
  copyright: "© Your Company — Location"
  legal:
    - Impressum: /impressum/
    - Datenschutz: /datenschutz/

footer.links must be a dict of groups (not a flat list). BUILD REFUSED if you use a list format like [{title: Imprint, url: /imprint/}].

The linter (RULE-32) enforces that every site has Impressum and Datenschutz links, as required by EU/German law.

Theme Customization

All components use Wire's CSS variables. Customize colors in wire.yml:

theme:
  primary_color: "#6200ea"   # Stats values, buttons, card hover, banner background
  accent_color: "#ffc107"    # Callouts, code highlights
  text_color: "#333"         # Body text, card descriptions
  font_family: "Inter"       # All text including component labels

Wire does not ship dark mode. Customers who want prefers-color-scheme: dark add it in their own extra.css with colors they've verified for contrast.

Page Layouts

Wire ships three page layouts. Set the layout in your frontmatter:

Layout Sidebar Content width Use case
page (default) Yes 740px Documentation, guides, articles
landing No 100% (you control everything) Homepages, marketing pages, product pages
raw No 100% (you control everything) Custom apps, interactive tools, embedded widgets

Landing pages

---
title: My Landing Page
description: Marketing page with full-width sections.
layout: landing
---

Landing pages give you full freedom: no width constraints, no injected H1. You own the entire layout. Wire only provides the landing-content wrapper class and the section system (split at --- into hero/light/accent bands).

Raw pages

---
title: Slide Editor
description: Interactive presentation editor.
layout: raw
extra_css:
  - /assets/css/slides.css
extra_js:
  - /assets/js/slides.js
---

Raw pages render your markdown/HTML directly into <main> with no <article> wrapper, no sidebar, and no content width constraints. You own the entire page body.

Custom CSS and JS

Any page can load additional assets via frontmatter. Works with all layouts:

extra_css:
  - /assets/css/custom.css
  - https://cdn.example.com/lib.css
extra_js:
  - /assets/js/custom.js

CSS files load in <head> after wire.css. JS files load with defer at the end of <body>.

For site-wide CSS that applies to every page, use extra_css at the top level of wire.yml instead of per-page frontmatter:

# wire.yml
extra_css:
  - assets/css/brand.css

Site-wide CSS loads after wire.css but before per-page extra_css, so page-level overrides always win.

Migrating from MkDocs

Wire refuses to build files containing MkDocs extension syntax. Replace these patterns:

MkDocs syntax Wire equivalent
<div class="stats" markdown> :::stats
<div class="grid" markdown> :::cards
<div class="split" markdown> :::split
<div class="banner" markdown> :::banner VALUE
[text](url){ .md-button } :::cta with {primary}
!!! note "Title" > blockquote
=== "Tab" ## heading

Terminal Block

Use the terminal language tag on a fenced code block to render a styled command showcase. Lines are parsed by prefix:

Prefix Renders as Use for
$ Prompt + command Commands the user runs
# Comment Explanations between commands
+ Green output Success messages
- Red output Error messages
-- text -- Yellow header Section separators
(other) Muted output Standard command output
```terminal
# Install Wire
$ pip install wire
+ Successfully installed wire-0.0.0

# Build your site
$ python -m wire.build
- ERROR: wire.yml not found
```

Automatic Features

These features are enabled on every Wire site with zero configuration.

Table of Contents

Pages with 3+ headings get an inline TOC below the page title. Uses h2 and h3 headings. Collapsible via click. Not shown on landing pages.

Reading Progress Bar

A thin accent-colored bar at the top of the viewport shows how far the reader has scrolled. Visible on all pages.

Back to Top

A circular button appears in the bottom-right corner after scrolling 400px. Smoothly scrolls back to the top of the page.

Code Copy Button

A "Copy" button appears on hover over any code block. One click copies the code to the clipboard. Shows "Copied!" confirmation for 2 seconds.

External links (opening in a new tab) get a small arrow to signal they leave the site.

Smooth Scrolling

All anchor links scroll smoothly. Heading anchors account for the sticky header height so content isn't hidden behind it.

Scroll Title

When the reader scrolls past the page H1, the article title appears next to the site logo in the header bar. Fades out when scrolling back up.

See the Guides overview for all Wire documentation.