On this page
- Three Ways to Use Wire
- What Wire Generates
- Quick Start with Init
- Manual Setup
- Content Structure
- Customizing Prompts
- Wire Configuration
- Templates and Assets
- How Overrides Work
- Default Templates
- Default JS (zero config)
- Building
- GitHub Pages
- Connecting GSC
- What Wire Does on Day One
- Sites Wire Works Best With
- Build Output Files
- JSON-LD Timestamps
Wire works with any site that has markdown content in a structured directory. The init command generates everything you need, or you can create the config manually.
Three Ways to Use Wire
Standalone homepage. Wire builds and hosts your full site. You get navigation, SEO, search, RSS feed, sitemap, and 91 lint rules on every build. This is the default.
Headless CMS. Wire creates optimized articles. You copy the content to your existing site. Wire handles quality, SEO, and freshness; your site handles design and hosting. The docs/ directory is your content source.
Linter only. You already have a website and just want Wire to check content quality. Two commands, no migration:
cd /path/to/your/articles
python -m wire.chief init # Creates wire.yml, discovers existing markdown
python -m wire.build # Runs 91 lint rules, reports every issue
The build output in site/ can be ignored. The value is in the lint report. If you want to fix issues automatically: python -m wire.chief lint-fix (low token usage).
What Wire Generates
Every build produces these automatically:
sitemap.xmlandrobots.txt- JSON-LD structured data (Article, FAQ, NewsArticle, author pages)
llms.txtfor LLM discovery- RSS/Atom feed
- Search page with client-side search index
- Open Graph and Twitter Card meta tags
- 91 lint rules checking every page
Hosting is free. Wire generates a static site. Host on GitHub Pages (free, custom domain), Netlify (free tier), Vercel, or any web server. See the GitHub Pages deploy workflow below.
Quick Start with Init
cd /path/to/my-site
python -m wire.chief init
Wire generates wire.yml, _styleguide.md, templates, and a .env template. If mkdocs.yml exists, Wire migrates settings from it: site name, URL, docs directory, theme colors, and extra.wire configuration.
Wire requires wire.yml for building (python -m wire.build). The editorial pipeline (chief, content, news) also reads mkdocs.yml as a legacy fallback during migration, but logs a warning nudging you to create wire.yml.
Manual Setup
Create a wire.yml config file and a docs/ directory with markdown content. Templates and CSS are optional. Wire ships sensible defaults.
# wire.yml
site_name: My Agency Blog
site_url: https://blog.agency.com
description: B2B marketing insights and case studies.
docs_dir: docs
templates_dir: templates
output_dir: site
Define your site structure in nav:. Wire does not auto-discover topics. Navigation is a strategic decision. Every section and page must be explicitly declared.
Content Structure
Wire expects this file layout:
docs/
index.md # Homepage
insights/ # Topic: insights
index.md # Topic index page
content-strategy/
index.md # Content page
seo-fundamentals/
index.md # Content page
case-studies/ # Topic: case-studies
index.md
client-a/
index.md
Every index.md needs YAML frontmatter with at least title. Wire uses the directory name as the slug and the parent directory as the topic.
Customizing Prompts
Wire's built-in prompts work for most sites. To customize how Claude writes for a specific topic, create a prompt override.
docs/
_styleguide.md # Site-wide editorial rules
insights/
_create.md # Custom create prompt for insights topic
_update.md # Custom update prompt for insights topic
Place _styleguide.md in your docs root for site-wide rules. Place _{action}.md in any topic directory for topic-specific instructions. Wire prepends the styleguide to every prompt automatically.
See the prompt engineering guide for details on writing effective prompts.
Wire Configuration
Optional settings go under extra.wire in your wire.yml:
extra:
wire:
refresh_days:
insights: 30
case-studies: 90
default_refresh_days: 60
reword_tiers:
full: 20
light: 30
max_articles: 20
rate_limit_delay: 1
min_opportunity_score: 15
See the configuration reference for all available options.
Templates and Assets
Wire ships default templates and CSS/JS. You only override what you want to change.
How Overrides Work
Wire checks your templates/ directory first, then falls back to wire/templates/. Same file name = your version wins. This is how Wire's own documentation site works. It overrides only the header (for the "Wire" logo) and keeps everything else default:
newsroom/
templates/
partials/
header.html # Custom: hardcoded "Wire" logo
wire/
templates/
base.html # Default: used as-is
page.html # Default: used as-is
landing.html # Default: used as-is
partials/
header.html # Ignored: overridden above
nav.html # Default: used as-is
footer.html # Default: used as-is
Assets work the opposite direction for safety. Wire copies its defaults first (wire/assets/), then overlays your files (docs/assets/) on top. Your CSS/JS files overwrite the defaults with the same name.
wire/assets/ # Copied first (defaults)
css/wire.css
js/scroll-title.js
js/toc-spy.js
js/back-to-top.js
...
docs/assets/ # Overlaid second (your overrides)
css/wire.css # Replaces default CSS
images/logo.png # Added alongside defaults
Default Templates
| Template | Purpose |
|---|---|
base.html | HTML skeleton: head, body, header, nav, main, footer |
page.html | Article layout: TOC, reading progress, content |
landing.html | Full customer freedom, splits at <hr> into section bands, no width constraints |
raw.html | Minimal wrapper, no nav or chrome |
partials/header.html | Site header with logo and navigation |
partials/nav.html | Sidebar navigation with active states |
partials/footer.html | Site footer |
Templates receive a page object (title, description, html, url, reading_time, word_count, meta), a nav list (sections with children), and a site dict (name, url, description).
reading_time is calculated at 220 words per minute (minimum 1 minute). It appears in JSON-LD structured data as wordCount and timeRequired (ISO 8601 duration, e.g. PT5M for a 5-minute read).
Default JS (zero config)
These features work automatically on every page, no configuration needed:
| File | What it does |
|---|---|
scroll-title.js | Replaces site name with page title when scrolling past header |
toc-spy.js | Highlights current section in table of contents |
back-to-top.js | Fixed button appears after 400px scroll |
reading-progress.js | Thin bar at top tracking scroll position |
code-copy.js | "Copy" button on code blocks, appears on hover |
discovery.js | Interactive guided reading (requires steps.md) |
yt-embed.js | Lazy-loads YouTube embeds from thumbnail |
tabs.js | Tab component for content switching |
forms.js | Form validation and submission |
Building
cd /path/to/my-site
python -m wire.build --site .
The output goes to site/ by default. Deploy it to any static hosting: Netlify, Vercel, S3, SiteGround, or a simple web server.
GitHub Pages
Create .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [master]
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Wire
run: |
curl -L -o /tmp/wire-0.0.0-py3-none-any.whl \
https://wire.wise-relations.com/dist/wire-0.0.0-py3-none-any.whl
pip install /tmp/wire-0.0.0-py3-none-any.whl
- name: Build site
run: python -m wire.build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: site
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Enable GitHub Pages in your repository settings (Settings > Pages > Source: GitHub Actions). Pushes to master trigger a build and deploy automatically.
If your repository URL is https://github.com/you/my-site, the site deploys to https://you.github.io/my-site/. Set site_url in wire.yml to match. Wire derives the subdirectory path from the URL automatically.
Connecting GSC
If your site is verified in Google Search Console, add OAuth credentials to .env and run python -m wire.chief data. This enables all SEO automation features: keyword analysis, cannibalization detection, opportunity scoring, and content gap detection.
GSC integration is optional. Wire's content pipeline and news intelligence work without it.
What Wire Does on Day One
A new site connected to Wire immediately benefits from three automated capabilities that would take a human team weeks to replicate.
Structural audit. Wire scans every page for the issues that Screaming Frog's 2024 data shows average 3.2 per 100 pages: duplicate titles, missing H1 tags, broken internal links, heading hierarchy violations, thin content, missing meta descriptions. The audit runs in seconds and costs nothing.
Cannibalization detection. If you connect GSC, Wire runs a SQL self-join across all keyword-page combinations to find pages competing for the same search terms. First Page Digital uses 30% shared impressions as the cannibalization threshold. Wire uses a dual signal (overlap ratio + traffic skew) that is more precise. It distinguishes between a dominant page absorbing a weak one (merge) and two pages confusing Google equally (differentiate both).
Content gap identification. Wire finds keywords where search demand exists (impressions) but no page on your site ranks well (best position above 20). These represent opportunities for new content. On a typical 100-page B2B site, Wire identifies 5-15 content gap clusters on the first audit.
The first week with Wire typically follows this pattern:
- Day 1: Connect the site, run
dataandaudit. Review findings. - Day 2: Run
deduplicateto resolve cannibalization. Review merges with--dry-runfirst. - Day 3: Run
sanitizeto fix broken internal links (zero cost, no API calls). - Day 4: Run
enrichon the highest-opportunity pages. Minimal token usage. - Day 5: Run
buildand deploy.
By end of week one, you have resolved keyword cannibalization, fixed structural issues, and enriched your best pages with targeted keyword content. Total token usage for a 100-page site is minimal, covered by your AI subscription. See pricing.
Sites Wire Works Best With
Wire is built for content-heavy sites where search traffic matters. The sweet spot is 50-2,000 pages of informational or commercial content: product pages, service descriptions, guides, comparisons, industry analysis.
Wire is not the right tool for single-page applications, e-commerce product catalogs with thousands of identical templates, or sites where content is generated from a database (job boards, real estate listings). These sites need different architectures.
The sites that get the most value from Wire share three characteristics: they have enough pages that manual SEO is impractical, they compete for search traffic in a defined niche, and they have (or can get) Google Search Console access for their domain.
Build Output Files
Wire auto-generates these files during every build:
| File | Purpose |
|---|---|
sitemap.xml | Page index for search engines |
robots.txt | Crawler access rules with Sitemap directive |
feed.xml | RSS feed, sorted by date descending, 20 most recently modified pages |
feed_rss_created.xml | Legacy alias, same content as feed.xml |
search_index.json | Client-side search data (full page body + all frontmatter metadata) |
llms.txt and llms-full.txt | AI-readable site summaries |
.htaccess | Apache redirect rules (when deploy.target: apache) |
404.html | Custom 404 error page |
CNAME | GitHub Pages custom domain (when configured) |
bot/ | Agent-facing site context (opt-in via extra.wire.bot_dir: true) |
.wire/build-errors.txt | All gate + lint errors persisted for reference after build |
JSON-LD Timestamps
Wire maps created to datePublished and date to dateModified in JSON-LD and OG meta tags (article:published_time/article:modified_time). Date-only values (2026-02-10) are auto-converted to full ISO 8601 timestamps. Google requires full timestamps to display dates in SERP snippets.
- Today's date: uses the real current time (never claims a future time on today's date)
- Past dates: derives a deterministic time from the date string (consistent across pages and builds)
- Safe for multiple builds per day. Same past date always produces same timestamp.
Author JSON-LD includes jobTitle from the author page's role: frontmatter for E-E-A-T.
See the Guides overview for all Wire documentation.