← All articles

Building an Automated Blog Pipeline with Astro and n8n

How I built an automated blog pipeline using Astro for crawlable HTML and n8n content automation to take raw notes from form to live post in about a minute.

Diagram of an automated blog pipeline flowing from an intake form through n8n and Claude to a GitHub commit and Netlify rebuild

The old Claude Design site shipped a client-side JS bundle that returned an empty Unpacking... shell to Googlebot. That’s a dead blog as far as search crawlers are concerned — no real HTML, nothing to index. So before automating anything, I had to fix what crawlers actually see.

The build

The base is a static Astro site. That’s the whole point: crawlers get real, server-rendered HTML instead of a JS bundle that resolves to an empty shell. If Googlebot can’t read the post, the rest of the pipeline is pointless.

On top of that I built the content engine in n8n. The flow:

  1. An intake form takes raw build notes.
  2. Claude Opus 4.8 writes the teardown under a strict prompt — one that refuses to invent facts. When a detail is missing, it leaves a placeholder and marks the post as draft instead of papering over the gap.
  3. n8n commits the markdown straight to the GitHub repo.
  4. Netlify sees the commit and auto-rebuilds.

The refuse-to-invent rule in the prompt is the part I’d defend hardest. A content engine that fills gaps with plausible-sounding filler is worse than no engine — it generates work to fact-check later. Marking the post draft when something’s missing keeps the bad output from going live on its own.

What broke

Two real ones.

The hero image cropped to a square. The img tag had a height="630" attribute that overrode the CSS aspect-ratio. The HTML attribute won, so the image got squashed regardless of what the stylesheet said. Fix was height: auto so the CSS aspect-ratio could actually take effect.

The first n8n runs looked like they hung. Every run sat for 2–3 minutes before finishing. The cause: max_tokens was set to 8000 on a non-streaming HTTP node, so the form waited for the entire generation to complete before returning anything. Cutting max_tokens to 3500 brought runs down to ~30 seconds. On a non-streaming node you’re paying the full generation time as latency, so the token ceiling is effectively a latency setting — worth remembering.

The result

Before: every post was hand-written and hand-committed. After: paste notes into a form, and the article is live in about a minute.

Takeaway

This is worth building when you’re publishing often enough that hand-committing is the bottleneck, and when you can write a prompt strict enough to refuse invention — otherwise you’ve just automated the production of things you have to verify by hand. If you post rarely, skip it; the n8n flow and the strict prompt are more setup than a handful of manual commits justify. And whatever you automate, check what crawlers actually receive first — a fast pipeline feeding an unreadable site is just a faster way to publish into the void.