Vibe Coding Forem

Cover image for How I Built a Fully Automated SEO Blog for $0/Month (Cloudflare + Gemini API)
Nextrader
Nextrader

Posted on

How I Built a Fully Automated SEO Blog for $0/Month (Cloudflare + Gemini API)

I run Nextrader — an AI-Powered Trading Bot Platform for Deriv trading. To drive organic traffic, I built a fully automated blog that publishes fresh, SEO-optimized articles twice a day without me touching a thing.

Here's exactly how it works — the tech stack, architecture decisions, and lessons learned.

The Goal

  • Publish two trading-focused blog posts per day, fully automated.
  • Each post includes a unique topic, SEO title, meta description, full article content, and an AI-generated cover image.
  • Zero recurring cost — free tier everything.
  • No CMS, no WordPress, no maintenance.

deriv bot

The Stack

Layer Tool Cost
Runtime Cloudflare Workers (Hono.js) Free
Database Cloudflare D1 (SQLite) Free
Image Storage Cloudflare R2 Free
AI Text Gemini 2.5 Flash Free
AI Images Gemini 2.5 Flash (Image Mode) Free
Deploy GitHub Actions + Wrangler Free
Total $0/month

The "Two-Call" Gemini Trick

The biggest challenge with Gemini 2.5 Flash is thinking tokens. When you ask for JSON and a full article in one prompt, the thinking tokens corrupt the JSON output.

The fix: split it into two calls.

  1. Call 1 — Metadata only (small JSON): Returns the title, slug, meta description, tags, and an image prompt.
  2. Call 2 — Article content (plain text): Writes the full 600–800 word article as plain text. No JSON wrapping.

This gave me 100% reliable JSON parsing with zero corruption.

Unique Topics Forever

The early version used getDayOfYear() — meaning topics would reset every January 1st and eventually repeat. I fixed this by switching to days since the Unix epoch. Today is day 20,546. Unique topics until the heat death of the universe.

AI Image Generation

Each post gets a unique cover image from Gemini's image API, with:

  • 8 rotating color themes — deep blue, emerald, crimson, purple, teal, cyan, amber, rose.
  • Topic-specific scene composition described by the metadata call.
  • Varied layouts — close-ups, overhead desk shots, phone screens, laptops.
  • WASM compression using @jsquash/jpeg — reduces 1.1 MB PNGs down to ~50 KB JPEGs.

SEO Built In

Every post automatically gets:

  • Article JSON-LD structured data.
  • Open Graph tags.
  • Auto-generated sitemap.xml and robots.txt.
  • Clean slug URLs with no /post/ prefix.

Lessons Learned

  • Two-call LLM pattern: Never mix structured JSON and long-form text in a single prompt with thinking models.
  • WASM in Cloudflare Workers: Pass the .wasm binary manually via init(), or it fails silently at runtime.
  • Wrangler deploys wipe dashboard secrets: Keep all variables in wrangler.toml if the repo is private.
  • Route order matters in Hono: /:slug catches everything, so always register it last.
  • PNG vs. JPEG from Gemini: Detect magic bytes (0x89 0x50 = PNG, 0xFF 0xD8 = JPEG) to handle both formats.

The live blog auto-publishes at 08:00 and 20:00 UTC every day. No servers. No bills. Just Cloudflare Workers and Gemini doing the work.

Check out the live blog: blog.nextrader.live

Top comments (0)