Blog template setup
ReachPill delivers finished articles into your repo or webhook — but your site's template decides how they look. Ten minutes of template setup makes every future post land pixel-perfect: correct headings, a styled hero, images that never overflow.
What arrives, exactly
Every article is one markdown file plus its images. The frontmatter is four fields, always the same:
content/posts/why-we-killed-the-calendar.md --- title: "Why we killed the content calendar" slug: why-we-killed-the-calendar seo_description: "The calendar was never the asset — the pipeline is." date: 2026-08-28 --- <img src="../images/why-we-killed-the-calendar-1.png" alt="Hero: a calendar dissolving into a pipeline" /> <h2>The calendar was never the asset</h2> <p>...</p>
title— render it as the page's only<h1>. The body never contains an h1; its headings start at<h2>, so your hierarchy stays clean.slug— the filename stem and your URL path. Images are named after it too ({slug}-1.png,{slug}-2.png…), which reads well in the repo and in image SEO.seo_description— wire it to<meta name="description">andog:description. It's written to summarize, not to repeat the title.date—YYYY-MM-DD, the publish date in UTC.
The body is HTML — let it through
Inside the .md file, the article body is clean semantic HTML (h2/h3, p, ul/ol, blockquote, pre/code, img) rather than markdown syntax. Most generators pass raw HTML through by default — but some sanitize it away, which renders as a blank or half-empty post. Check yours:
- Hugo — goldmark strips raw HTML by default. Set
markup.goldmark.renderer.unsafe = truein your config (the HTML is your own content, not user input). - Jekyll — kramdown passes HTML through. Nothing to do.
- Astro — content collections render raw HTML in markdown. Nothing to do.
- Next.js / remark pipelines — add
rehype-raw(orallowDangerousHtmlon remark-rehype), or the HTML nodes are dropped silently. - Eleventy — markdown-it needs
html: true(many starters already set it).
The hero image
The first <img> in the body is the featured image, generated in the aspect you picked (16:9 by default) with alt text set. Two ways to treat it:
- Leave it in place — style the first image full-width at the top of the article. Zero template logic.
- Promote it to a hero slot — if your layout has a dedicated banner/card image, extract the first image in your template and use the remainder as the body. Use the same extraction for the post's social share image (
og:image) and index-page thumbnails.
CSS that makes it read well
A short checklist — most themes already do most of this:
img { max-width: 100%; height: auto; }— inline images must never overflow the column. A littleborder-radiusand vertical margin makes them feel placed, not pasted.- A readable measure: article text at
65–75chmax width,1.6+line height. - Distinct
h2/h3steps — articles use them to structure sections and scanning depends on the visual difference. - Styled
blockquoteandpre/codeblocks (with horizontal scroll onpre, not wrapping) — technical posts use both. - If your site has dark mode, check image and code-block backgrounds in both themes once.
Paths your build must serve
In Settings → Connections you choose the content path and the images directory. Articles land at {path}/{slug}.md and images at {imagesDir}/{slug}-{n}.png, referenced from the body by relative path. Two rules keep that working:
- The images directory must be inside what your build serves as static assets (e.g. Hugo's
static/, Astro'spublic/, or a page-bundle layout where images sit next to content). - If your build rewrites content URLs, make sure the relative
img srcpaths survive it — publish one test post and open every image.
Prove it once
Publish a test article
Generate a one-off article from the console and publish it (review mode holds it until you approve).
Open the live post
Check the h1, the hero, inline images, headings, a list, and a blockquote. Fix template gaps now — every future post inherits them.
Check the metadata
View source:
title,meta description,og:image. Then delete the test post with a normal git revert if you like — it's just a commit.
On a webhook instead?
The webhook payload carries the same contract as the file — frontmatter fields, the HTML body, and image URLs — so everything above still applies; your endpoint just does the placing. Cross-posts to dev.to set canonical_url to your site automatically, so your page stays the SEO original.