Docs · Working with Claude Code

The write-post Skill

Walkthrough of publishing a new blog post with correct front matter and SEO structure.

write-post publishes a new blog post the same way this docs site itself is built: a markdown file with front matter, no database table, no admin UI. The full front-matter reference lives at Writing a Blog Post; this page is the skill's own step-by-step, including the structural choices that decide whether a post actually gets cited by an AI assistant.

What the app already handles

Once the file exists, you don't write any of the following by hand: the canonical URL, Open Graph and Twitter tags, BlogPosting structured data, breadcrumbs, the sitemap entry, both feeds, the llms.txt listing, or the raw-markdown alternate at /blog/<slug>.md. All of it reads from the file you write.

The steps

  1. Pick the slug and confirm the gap. The filename is the URL: content/posts/<slug>.md serves at /blog/<slug>. Keep it short, lowercase, hyphenated, and stable, since changing it later breaks every inbound link. Don't name a post tags; that path is reserved for the tag index.
  2. Write the front matter. title, description, and pub_date are required. description does real work: it's the meta description, the social card text, the feed summary, and the line under the search result, all from one sentence. Add tags (each generates a /blog/tags/<tag> page), and cta_* fields only if this post needs a call to action different from the site-wide default.
  3. Structure it so it can be quoted. This is the part that decides whether an assistant cites the post. The title is the question, phrased the way someone actually types it. The first sentence of the body restates that question. A direct, concrete answer, a number, a list of names, a yes with its condition, lands within the first 80 words, written to be lifted out and shown with no surrounding context, because that's exactly what happens to it. The long version follows under ## headings that are near-questions themselves, each making sense read alone. Prefer specifics to adjectives, and state limits honestly: hedged, qualified claims get cited more, not less.
  4. Match the house voice. Plain, concrete, and agent-neutral. No em dashes anywhere in copy or metadata; a spec enforces this, so use a colon, a comma, or a full stop instead. Body headings start at ##, never #, since the # level renders from the front-matter title.
  5. Link internally, both directions. Link the new post to two or three existing ones, and add a link back to it from the most closely related existing post. An orphan post ranks badly and gets crawled late.
  6. Check it renders. bin/dev, then open /blog/<slug> and confirm code blocks highlight, the CTA is right, and the post shows up in /sitemap.xml, /feed.xml, and /llms.txt.
  7. Verify: bin/check green.

Notes

Set draft: true to keep a work in progress out of the index, the feeds, and the sitemap entirely. Raw HTML in a post is sanitized on purpose, so a <script> tag is dropped; widen the allowlist in app/services/markdown_renderer.rb if a post genuinely needs a tag it currently strips. Posts are baked into the deploy image, so publishing one means committing and deploying, not just saving a draft somewhere.

Next

See how to phrase a request so Claude Code reaches for the right skill on its own: Prompting Patterns.