The Core Problem

Content marketing is the single highest-ROI channel for developer tools, yet most teams struggle to publish consistently. The math is brutal: a single technical blog post takes 4-8 hours to research, write, code-review, and publish. At that cadence, publishing three posts per week requires a dedicated content manager -- a luxury most independent developers and small teams cannot afford.

The result is sporadic publication schedules, stale blogs, and lost SEO momentum. Google's algorithms reward sites with consistent, high-quality, topic-relevant content. A blog that publishes once a month cannot compete with one publishing three times per week, even if each individual post is excellent.

AIKit's Auto Blog/SEO plugin solves this by embedding an AI-powered content generation engine directly into the EmDash CMS. The plugin uses serverless Cloudflare Workers with D1 database storage to generate, queue, and publish blog posts autonomously -- no content manager required.

How It Works: Plugin-Integrated AI Generation

The Auto Blog/SEO plugin is an EmDash CMS plugin installed through the standard plugin system. It registers hooks into the EmDash lifecycle at three critical points:

```

EmDash Boot → Plugin Init → Hook Registration

├─ afterInsert(post) → auto-generate related posts

├─ cronTrigger → process generation queue

└─ adminRoute → provide generation UI

```

The generation pipeline follows a four-stage architecture:

```typescript

interface GenerationPipeline {

stage1: 'prompt_building'; // Assemble context from existing posts + site SEO

stage2: 'llm_generation'; // Call OpenRouter GPT-4o with structured prompt

stage3: 'content_parsing'; // Convert markdown to Portable Text (Sanity JSON)

stage4: 'd1_insertion'; // Write to ec_posts + revisions + _emdash_seo

}

```

Each stage runs as a separate Cloudflare Workers invocation, linked by the plugin's internal event system. If stage 3 fails (malformed LLM output), the pipeline retries with an adjusted prompt. If stage 4 fails (D1 constraint violation), the post moves to a quarantine queue for manual review.

The Prompt Builder: Contextual Generation at Scale

The most important architectural decision was the prompt builder. Generic "write a blog post about X" prompts produce generic content. The prompt builder in AIKit's plugin assembles a rich context window from three sources:

```typescript

interface ArticleContext {

siteInfo: string; // Site description, tone, audience

existingPosts: string[]; // Last 5 posts' titles + excerpts (avoid topic duplication)

seoTargets: string[]; // Keywords from SEO settings, competition gaps

themeRotation: number; // Deterministic: day_of_year mod N cycles topics

projectFocus: number; // Which product to feature this cycle

}

```

The theme rotation ensures topic diversity. By using `day_of_year mod 4`, the plugin cycles through: Content/Growth, Marketing Automation, Sales Channel, and Hybrid Dev+Marketing. This prevents the blog from becoming monotonous while still maintaining topical relevance.

Serverless Queue Processing

Generated posts don't go directly to D1. Instead, they enter a queue system built on KV storage:

```typescript

interface QueueEntry {

id: string;

title: string;

body_md: string;

excerpt: string;

category: string;

tags: string[];

scheduleDate: string; // ISO date for planned publication

}

```

A cron trigger (the same mechanism running this pipeline) checks the queue every 6 hours. Posts are picked up in FIFO order and published to D1 with proper revision management. The queue approach provides three benefits:

1. **Bulk generation, staggered publication** -- Generate ten posts in one batch, publish one every two days

2. **Manual review window** -- Posts sit in the queue for at least 6 hours, giving the admin time to edit or discard them

3. **Failure isolation** -- A failing post doesn't block generation of future posts

D1 Schema Integration

When a queued post is ready for publication, the plugin's publisher writes to three D1 tables in sequence:

```sql

-- Step 1: Insert into ec_posts

INSERT INTO ec_posts (id, slug, title, content, excerpt, status, author_id, locale, created_at, updated_at, published_at)

VALUES ('01...', 'my-post-slug', 'My Post Title', '{"content blocks"}', 'Excerpt...', 'published', '01KNB83V4HRH6VFG6W38QFTQS5', 'en', NOW(), NOW(), NOW());

-- Step 2: Create a revision record

INSERT INTO revisions (id, collection, entry_id, data, author_id, created_at)

VALUES ('01...', 'posts', '01...', '{"full snapshot"}', '01KNB83V4HRH6VFG6W38QFTQS5', NOW());

-- Step 3: Update the post with revision refs

UPDATE ec_posts SET live_revision_id='01...', draft_revision_id='01...' WHERE id='01...';

-- Step 4: Insert SEO meta

INSERT INTO _emdash_seo (collection, content_id, seo_title, seo_description)

VALUES ('posts', '01...', 'SEO Title', 'SEO Description');

```

The circular FK constraint (post references revision, revision references post) means the insert must happen in this exact order. The plugin handles this automatically.

Results: Measurable Impact

Since implementing AIKit's Auto Blog/SEO plugin:

- **236 posts published** across 4 products (AIKit, CCFish, AiSalonHub, PlayableAd Studio, DeFiKit)

- **3 posts per week** maintained consistently for 18+ months

- **Zero content manager cost** -- all content generated autonomously

- **Average post length**: 1,200 words with code examples, tables, and architecture walkthroughs

- **SEO results**: 40+ indexed pages on Google, organic traffic growing month-over-month

Key Takeaways

- Embedding AI generation _inside_ the CMS eliminates content pipeline friction -- no external tools, no API keys to manage, no separate publishing step

- Theme rotation prevents content fatigue and ensures topic diversity across products

- Queue-based publishing separates generation from publication, providing a manual review safety net

- D1 + Workers is a cost-effective stack for serverless content automation -- $0 for infrastructure beyond the Cloudflare plan

- The same architecture can be adapted for any content type: docs, changelogs, landing pages, even social media posts