SEO-GEO Blog Writer
Purpose
Create high-performing blog posts optimized for both traditional search engines (SEO) and generative AI citations (GEO) through a structured four-phase workflow: Research → Outline → Draft → Optimize.
When to Use This Skill
Activate when user requests blog content creation. Two modes supported:
Mode A - Keyword-Driven:
- "Write a blog post targeting 'best CRM for small business'"
- "Create an article optimized for 'React hooks tutorial'"
- "I need a post ranking for 'email marketing automation tools'"
Mode B - Topic Expansion:
- "Write a blog post about email marketing"
- "Create an article on React development"
- "I need content about CRM systems"
Both modes follow the same four-phase workflow after keyword selection.
Workflow Overview
Execute in seven phases:
- Research: Gather requirements, conduct keyword research, analyze search intent, identify citation-worthy sources
- Outline: Select content pattern, create structured outline with SEO-optimized headers and GEO-friendly sections
- Draft: Write comprehensive content following E-E-A-T principles with proper keyword placement
- Optimize: Initial content optimization and refinement
- Auto Internal Linking (NEW v2.2): Discover and insert high-confidence internal links from Sanity/local content
- Image Generation (Coming Week 3): Auto-generate and insert images using AI
- Final Validation: Iterative validation with auto-fix for FAQ, author bio, schema, title
Example Usage
Example 1: Mode B (Topic Expansion with Keyword Research)
User Request:
"Write a blog post about empath boundaries"
Execution Flow:
- Detect Mode B (general topic, no specific keyword)
- Execute keyword research:
python scripts/keyword_research.py "empath boundaries" --limit 5 --format markdown
- Present options to user:
Top keywords researched:
1. healthy boundaries for empaths (Vol: 2,400, Diff: 45, Score: 95)
2. how to set boundaries as an empath (Vol: 3,100, Diff: 52, Score: 92)
3. empath boundary setting tips (Vol: 1,200, Diff: 38, Score: 88)
Which would you like to target? (or 'auto' for best match)
- User selects: "Let's use #1" → Keyword confirmed: "healthy boundaries for empaths"
- Gather remaining requirements: audience, author details, word count (2,000 words recommended for Diff: 45)
- Load
references/content-patterns.md → Select "How-To Guide" pattern
- Create outline with keyword optimization
- Write draft following E-E-A-T guidelines
- Execute validation and deliver complete package
Output: 2,000-word how-to guide optimized for "healthy boundaries for empaths" with FAQ schema, validation report, and meta tags
Example 2: Mode A (Keyword-Driven)
User Request:
"Write a blog post about best email marketing tools for Shopify stores"
Execution Flow:
- Detect Mode A (specific long-tail keyword provided)
- Confirm keyword: "I'll optimize for 'best email marketing tools for Shopify stores'. Confirm?"
- Gather requirements: audience (Shopify store owners), word count (2,500), author details
- Load
references/content-patterns.md → Select "Comparison Article" pattern
- Load
references/seo-checklist.md → Extract keyword strategy
- Generate outline using
assets/blog-template.md structure
- Write draft following E-E-A-T guidelines from
references/eeat-guidelines.md
- Execute
scripts/validate_structure.py on draft
- Generate schema markup using
assets/structured-data-examples.json
- Deliver: blog post + schema markup + SEO checklist
Output: 2,500-word comparison article with FAQ schema, meta tags, and validation report
Implementation Instructions
Phase 1: Gather Requirements & Keyword Research
This skill supports two modes based on user input:
Mode A: Keyword-Driven (User provides specific target keyword)
Mode B: Topic Expansion (User provides general topic, needs keyword research)
Step 1: Detect Mode
Analyze user request to determine mode:
IF request contains specific keyword phrase in quotes → Mode A
Example: "Write post targeting 'healthy boundaries for empaths'"
ELSE IF request mentions specific long-tail keyword → Mode A
Example: "Write about best email marketing tools for Shopify stores"
ELSE IF request is general topic → Mode B
Example: "Write post about empath boundaries"
Example: "Create article on email marketing"
Step 2: Execute Mode-Specific Workflow
MODE A: Keyword-Driven Workflow
User has already identified target keyword. Proceed directly to validation:
- Confirm keyword with user: "I'll optimize this post for '[keyword]'. Confirm?"
- Collect remaining requirements:
- Target Audience
- Content Goal
- Author Details (name, credentials, bio, photo URL - critical for E-E-A-T)
- Word Count Target (1,500-3,000 words)
- Continue to Phase 2 (Research & Pattern Selection)
MODE B: Topic Expansion Workflow
User needs keyword research assistance. Execute keyword research:
Run keyword research script (with credential handling):
The script automatically tries multiple credential methods in order:
- Command line argument (
--api-key)
- Environment variable (
DATAFORSEO_API_KEY)
- Config file (
~/.dataforseo-skill/config.json)
- Fallback to heuristic mode (no API needed)
IMPORTANT FOR CLAUDE CODE ENVIRONMENT:
Option A: Ask user for API key (if they want real data):
Claude: "Would you like to use the DataForSEO API for real keyword data?
If yes, please provide your API key in format: login:password
If no, I'll use fallback mode with intelligent estimates."
IF user provides key:
python scripts/keyword_research.py "user topic" --limit 5 --format markdown --api-key "user_provided_key"
ELSE:
python scripts/keyword_research.py "user topic" --limit 5 --format markdown
Option B: Use fallback mode directly (faster, no credentials needed):
# Fallback mode works without any credentials
python scripts/keyword_research.py "user topic" --limit 5 --format markdown
DO NOT use --interactive flag - it doesn't work in Claude Code's non-TTY environment.
Note: The script automatically falls back to heuristic mode if:
- No credentials found
- API call fails (invalid credentials, rate limit, etc.)
- Script provides intelligent keyword suggestions without API
Present options to user:
Display top 3-5 keywords with metrics:
- Search volume (monthly searches)
- Keyword difficulty (0-100, lower = easier to rank)
- Relevance score (0-100, higher = better match)
Example output:
I've researched keywords for "empath boundaries". Top options:
1. healthy boundaries for empaths (Vol: 2,400, Diff: 45, Score: 95)
2. empath boundary setting tips (Vol: 1,200, Diff: 38, Score: 88)
3. how to set boundaries as an empath (Vol: 3,100, Diff: 52, Score: 92)
Which keyword would you like to target? (or type 'auto' for best match)
Handle user selection:
Option 1: User selects specific keyword
User: "Let's use #2"
→ Proceed with selected keyword
Option 2: User requests auto-selection
User: "auto" or "pick the best one"
→ Select highest relevance score
→ Inform user: "Auto-selected: [keyword] (best relevance score)"
Collect remaining requirements (same as Mode A)
Continue to Phase 2
Step 3: Validation & Optimization Notes
For Mode B keywords (researched via script):
- Note search volume in outline planning (high volume = more comprehensive content needed)
- Adjust word count based on keyword difficulty:
- Difficulty 0-30: 1,500-2,000 words sufficient
- Difficulty 31-60: 2,000-2,500 words recommended
- Difficulty 61-100: 2,500-3,000+ words required
Fallback Handling
If scripts/keyword_research.py fails or is unavailable:
- Inform user: "Keyword research tool unavailable. Using heuristic analysis."
- Generate 3-5 variations manually using common patterns:
- "best [topic]"
- "how to [topic]"
- "[topic] guide"
- "[topic] tips"
- "[topic] for beginners"
- Present options with estimated competitiveness
- Continue workflow normally
Phase 2: Research and Pattern Selection
Research Steps:
- Identify search intent: Informational, commercial, transactional, or navigational
- Load
references/seo-checklist.md → Extract keyword strategy and meta optimization tactics
- Analyze top-ranking content patterns
- Gather citation-worthy sources: statistics, studies, expert quotes
Pattern Selection:
Load references/content-patterns.md and select appropriate structure:
- Ultimate Guide: Comprehensive topics (2,000+ words)
- How-To Guide: Process-oriented content (1,500-2,500 words)
- Comparison/Review: Product comparisons (2,000-3,000 words)
- Listicle: Roundups and curated lists (1,000-2,500 words)
- Data-Driven Research: Original research posts (2,000-4,000 words)
Phase 3: Create Outline
Generate structure including:
- SEO-optimized title (primary keyword within first 60 characters)
- Introduction with hook and primary keyword in first 100 words
- 4-8 H2 sections with keyword variations
- FAQ section (4-8 questions minimum)
- Conclusion with clear CTA
- Author bio section
Use assets/blog-template.md as structural reference.
Phase 4: Write Draft
Load references/eeat-guidelines.md and apply E-E-A-T principles:
Experience signals:
- Include first-hand experiences, testing results, or case studies
- Use specific examples and real scenarios
- Add screenshots, data, or proof when applicable
Expertise signals:
- Cite authoritative sources with proper attribution
- Include expert quotes or interviews
- Reference recent studies and statistics (with dates)
- Use precise, accurate terminology
Authoritativeness signals:
- Link to authoritative external sources (2-4 per article)
- Build topical clusters with internal links (3-5 per article)
- Demonstrate comprehensive topic coverage
Trustworthiness signals:
- Add author bio with credentials
- Include last updated date
- Provide accurate, verifiable information
- Add disclosures where relevant (affiliate links, sponsorships)
GEO Optimization:
Load references/geo-optimization.md for AI citation formatting:
- Start sections with clear, quotable statements
- Use "According to [Source]" attribution format
- Include statistics with sources and dates
- Structure data in easily extractable formats (tables, lists)
- Provide direct, concise answers in FAQ (40-60 word paragraphs)
- Include "what, why, how" question variations
Phase 5: Auto Internal Linking (NEW v2.2)
Automated internal link discovery and insertion:
Discover existing content from configured sources:
# Test content discovery first
python scripts/content_sources.py \
--sanity-project-id $SANITY_PROJECT_ID \
--local-content ./blog-posts
Content source priority:
- Sanity CMS API (if
SANITY_PROJECT_ID configured)
- Local markdown directory (if
--local-content provided)
- Fallback to empty (no links inserted)
Auto-insert internal links into draft:
python scripts/auto_internal_linking.py /tmp/blog_draft.md \
--sanity-project-id $SANITY_PROJECT_ID \
--min-confidence 90 \
--max-links 5 \
--output /tmp/blog_draft_linked.md
Link insertion process:
The script automatically:
- Discovers existing blog posts from configured sources
- Analyzes relevance between draft and existing content
- Identifies high-confidence linking opportunities (≥90 relevance)
- Inserts markdown links for first keyword occurrence
- Avoids over-linking (max 5 links by default)
Example output:
✓ Found 50 existing pages for internal linking
✓ Found 8 total suggestions
→ 5 high-confidence (≥90)
✓ Successfully inserted 5 links:
1. Email marketing → /blog/email-marketing-guide (95)
2. Marketing automation → /blog/automation-best-practices (92)
3. Customer segmentation → /blog/segmentation-strategies (91)
4. Email campaigns → /blog/campaign-optimization (90)
5. ROI tracking → /blog/marketing-metrics (90)
Configuration options:
Via command line:
# Sanity CMS (recommended)
python scripts/auto_internal_linking.py draft.md \
--sanity-project-id your-project-id \
--sanity-dataset production
# Local markdown files
python scripts/auto_internal_linking.py draft.md \
--local-content ./blog-posts
# Adjust confidence threshold
python scripts/auto_internal_linking.py draft.md \
--local-content ./posts \
--min-confidence 85 # Lower threshold for more links
Via environment variables:
export SANITY_PROJECT_ID=your-project-id
export SANITY_DATASET=production
python scripts/auto_internal_linking.py draft.md
Via config file: .seo-geo-config.json
{
"sanity": {
"project_id": "your-project-id",
"dataset": "production"
},
"internal_linking": {
"min_confidence_auto_insert": 90,
"max_links_per_post": 5
}
}
Continue to Phase 6 (Image Generation) or Phase 7 (Final Validation)
Phase 6: Image Generation (NEW v2.2)
Automated image generation and insertion using AI APIs:
Generate professional blog post images automatically using Google Imagen or OpenAI DALL-E 3. The system extracts image placeholders, classifies image types, generates appropriate images, and inserts them into your draft.
1. Add image placeholders to your draft (optional):
During Phase 4 (drafting), add placeholders where you want images:


Note: Featured/hero image is auto-generated if not present.
2. Generate images:
Option A - OpenAI DALL-E 3 (easiest setup):
export OPENAI_API_KEY=sk-...
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md \
--max-images 5
Option B - Google Imagen (requires Google Cloud):
export GOOGLE_API_KEY=...
export GOOGLE_PROJECT_ID=my-project
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md \
--max-images 5
Option C - Use configuration file:
# Configure in .seo-geo-config.json:
{
"image_generation": {
"enabled": true,
"google_api_key": "...",
"google_project_id": "...",
"openai_api_key": "sk-...",
"max_images_per_post": 5,
"output_dir": "./generated_images"
}
}
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md
3. Test extraction without API keys (dry-run):
python scripts/image_generation.py /tmp/blog_draft.md --dry-run
# Output shows:
# - Number of images that would be generated
# - Image type and style classification
# - Alt text and context for each image
How it works:
Extract Image Needs:
- Finds all
 patterns
- Auto-adds featured/hero image if none exists
- Classifies image type (featured, section, diagram)
- Determines appropriate style (photorealistic, illustration, diagram)
Generate Images:
- Priority 1: Google Imagen ($0.02/image, $2000 startup credit)
- Priority 2: OpenAI DALL-E 3 ($0.04-$0.08/image, Microsoft credits)
- Optimized prompts for each style and image type
- Downloads and saves images locally
Insert Into Draft:
- Replaces
(placeholder) with actual image paths
- Updates alt text for SEO
- Preserves markdown formatting
Image Classification:
Featured/Hero Images: Photorealistic style, 1792x1024px
- Trigger: First image or auto-generated from title
- Example: "Professional email marketing dashboard"
Section Images: Illustration style, 1024x1024px
- Trigger: Images within content sections
- Example: "Email list building strategy"
Diagrams/Infographics: Technical diagram style, 1024x1024px
- Trigger: Keywords like "diagram", "flowchart", "workflow", "infographic"
- Example: "Email automation workflow diagram"
Cost tracking:
The script shows total generation cost and per-image pricing for budget management.
Generated output structure:
/tmp/blog_draft_with_images.md ← Updated draft with images
./generated_images/ ← Image directory
├── image_abc123.png ← Featured image
├── image_def456.png ← Section image 1
└── image_ghi789.png ← Diagram
Phase 7: Final Validation and Auto-Fix
Validation Protocol (ALWAYS EXECUTE):
Write draft to temporary file:
# Save draft to /tmp/blog_draft.md
Execute iterative validation with auto-fix:
python scripts/iterative_validation.py /tmp/blog_draft.md \
--max-iterations 3 \
--target-score 80 \
--output /tmp/blog_draft_final.md
Iterative validation process:
The script automatically:
- Validates current draft state
- Auto-fixes common issues (FAQ, author bio, schema templates, title length)
- Re-validates after fixes
- Stops when: score ≥80 OR max 3 iterations OR no more auto-fixable issues
Auto-fixable items:
- Missing FAQ section → Generates 4-6 questions from H2 headings
- Missing author bio → Adds template (user fills details later)
- Short title (<50 chars) → Expands with year or descriptive phrases
- Missing schema → Adds BlogPosting and FAQPage templates
Non-auto-fixable items (require manual attention):
- Low word count → Note thin sections for expansion
- Missing internal/external links → Needs content research
- Missing images → Needs image sourcing or generation
- Low readability score → Needs content restructuring
Interpret results:
Final Score: 88/100
Fixes Applied (4):
✓ Added FAQ section with 6 questions
✓ Added author bio template (requires user completion)
✓ Expanded title: 'Tips' → 'Complete Tips Guide 2025'
✓ Added schema markup templates (requires completion)
✓ PASSED (8 checks): Title optimal, Word count good, FAQ present...
⚠ WARNINGS (3 items): Internal links low, Images needed...
- Score ≥80: Excellent, proceed to delivery
- Score 60-79: Review warnings, address critical ones
- Score <60: Fix FAILED checks manually, re-run validation
Complete placeholders in auto-generated content:
- Author bio: Replace
[Author Name], [job title], [X years] with real details
- Schema markup: Fill in
[YYYY-MM-DD], [Meta description], [Featured image URL]
- FAQ answers: Expand auto-generated summaries if needed
Handle script failure:
If script unavailable, use manual validation with references/seo-checklist.md:
- Primary keyword in title, H1, first 100 words, URL slug, meta description
- 2-3 H2 headings with keyword variations
- Internal links (3-5) and external authority links (2-4)
- Images with optimized alt text
- FAQ section with schema markup
- Author bio with credentials
- Meta title (50-60 chars) and description (145-155 chars)
Deliver final package:
- Complete blog post with auto-fixes applied (
/tmp/blog_draft_final.md)
- Validation report showing score and fixes applied
- Schema markup code blocks (with placeholders to complete)
- SEO checklist with verification status
- Image suggestions with alt text
- Internal linking recommendations
Resource Loading Strategy
When to Load Each Reference
Requirements Phase (Load if needed):
- Execute
scripts/keyword_research.py → When Mode B detected (topic expansion needs keyword research)
Planning Phase (Always load):
- Read
references/content-patterns.md → Select appropriate pattern based on topic and search intent
Research Phase (Load if needed):
- Read
references/seo-checklist.md → When conducting keyword research or meta optimization
- Read
references/geo-optimization.md → When planning citation-worthy formatting
Draft Phase (Load selectively):
- Read
references/eeat-guidelines.md → When writing sections requiring credibility signals
- Use
assets/blog-template.md → As structural reference for section organization
Validation Phase (Always execute):
- Execute
scripts/validate_structure.py → After completing draft
- Read
assets/structured-data-examples.json → When generating schema markup
Token Efficiency for Large Files
references/content-patterns.md is 758 lines. For targeted reading:
# Read only specific pattern instead of entire file
grep -A 100 "## Pattern 2: How-To Guide" references/content-patterns.md
This approach: ~400 tokens vs ~3,000 tokens for full file.
Output Deliverables
Provide complete package:
- Blog post in markdown (using
assets/blog-template.md structure)
- SEO checklist with verification status for each item
- Schema markup code blocks (BlogPosting + FAQPage)
- Image suggestions with optimized alt text
- Internal linking recommendations with anchor text
- Validation report from script execution
Critical Requirements (What NOT to Do)
Avoid these quality-damaging practices:
- Thin content (<1,000 words for competitive topics)
- Keyword stuffing (maintain natural readability)
- Unverifiable claims or missing citations
- Missing author credibility (E-E-A-T critical for rankings)
- Poor mobile readability (short paragraphs required)
- Clickbait tactics (damages trustworthiness signals)
- Copying competitor content (use as pattern inspiration only)
- Skipping FAQ section (critical for GEO optimization)
- Missing schema markup (required for rich results)
- No author bio (damages E-E-A-T scoring)
Quality Targets
Target these metrics for optimal performance:
- Readability score: 60-70 (Flesch Reading Ease)
- Keyword density: 1-2% for primary keyword
- Heading hierarchy: Proper H1 → H2 → H3 structure
- FAQ section: 4-8 questions with schema markup
- Internal links: 3-5 with descriptive anchor text
- External links: 2-4 to authoritative sources
- Images: 5-8 with optimized alt text
- Word count: 1,500-3,000 (adjust for competition)
- E-E-A-T signals: Author bio, citations, first-hand experience
- Schema markup: BlogPosting + FAQPage minimum
Optimization Factors for Best Results
Input Quality:
- Specific topic details improve output precision
- Real author credentials significantly improve E-E-A-T scoring
- Existing case studies or data enhance content quality
- Clear target audience definition enables better targeting
Process Optimization:
- Request outline approval before full draft to ensure direction alignment
- Execute validation script to catch structural issues early
- Plan content refresh every 6-12 months for freshness signals
Related Skills
- blog-optimizer: Improve existing posts (different workflow from creation)
- content-repurposer: Convert blog posts to other formats (separate use case)
---
name: seo-geo-blog-writer
description: Create blog posts optimized for traditional search engines (SEO) and generative AI citations (GEO). Supports two modes - keyword-driven (user provides target keyword) or topic expansion (automated keyword research). Complete workflow from keyword research through schema markup generation.
---
# SEO-GEO Blog Writer
## Purpose
Create high-performing blog posts optimized for both traditional search engines (SEO) and generative AI citations (GEO) through a structured four-phase workflow: Research → Outline → Draft → Optimize.
## When to Use This Skill
Activate when user requests blog content creation. Two modes supported:
**Mode A - Keyword-Driven:**
- "Write a blog post targeting 'best CRM for small business'"
- "Create an article optimized for 'React hooks tutorial'"
- "I need a post ranking for 'email marketing automation tools'"
**Mode B - Topic Expansion:**
- "Write a blog post about email marketing"
- "Create an article on React development"
- "I need content about CRM systems"
Both modes follow the same four-phase workflow after keyword selection.
## Workflow Overview
Execute in seven phases:
1. **Research**: Gather requirements, conduct keyword research, analyze search intent, identify citation-worthy sources
2. **Outline**: Select content pattern, create structured outline with SEO-optimized headers and GEO-friendly sections
3. **Draft**: Write comprehensive content following E-E-A-T principles with proper keyword placement
4. **Optimize**: Initial content optimization and refinement
5. **Auto Internal Linking** (NEW v2.2): Discover and insert high-confidence internal links from Sanity/local content
6. **Image Generation** (Coming Week 3): Auto-generate and insert images using AI
7. **Final Validation**: Iterative validation with auto-fix for FAQ, author bio, schema, title
## Example Usage
### Example 1: Mode B (Topic Expansion with Keyword Research)
**User Request:**
"Write a blog post about empath boundaries"
**Execution Flow:**
1. **Detect Mode B** (general topic, no specific keyword)
2. **Execute keyword research:**
```bash
python scripts/keyword_research.py "empath boundaries" --limit 5 --format markdown
```
3. **Present options to user:**
```
Top keywords researched:
1. healthy boundaries for empaths (Vol: 2,400, Diff: 45, Score: 95)
2. how to set boundaries as an empath (Vol: 3,100, Diff: 52, Score: 92)
3. empath boundary setting tips (Vol: 1,200, Diff: 38, Score: 88)
Which would you like to target? (or 'auto' for best match)
```
4. **User selects:** "Let's use #1" → Keyword confirmed: "healthy boundaries for empaths"
5. **Gather remaining requirements:** audience, author details, word count (2,000 words recommended for Diff: 45)
6. Load `references/content-patterns.md` → Select "How-To Guide" pattern
7. Create outline with keyword optimization
8. Write draft following E-E-A-T guidelines
9. Execute validation and deliver complete package
**Output:** 2,000-word how-to guide optimized for "healthy boundaries for empaths" with FAQ schema, validation report, and meta tags
### Example 2: Mode A (Keyword-Driven)
**User Request:**
"Write a blog post about best email marketing tools for Shopify stores"
**Execution Flow:**
1. **Detect Mode A** (specific long-tail keyword provided)
2. **Confirm keyword:** "I'll optimize for 'best email marketing tools for Shopify stores'. Confirm?"
3. **Gather requirements:** audience (Shopify store owners), word count (2,500), author details
4. Load `references/content-patterns.md` → Select "Comparison Article" pattern
5. Load `references/seo-checklist.md` → Extract keyword strategy
6. Generate outline using `assets/blog-template.md` structure
7. Write draft following E-E-A-T guidelines from `references/eeat-guidelines.md`
8. Execute `scripts/validate_structure.py` on draft
9. Generate schema markup using `assets/structured-data-examples.json`
10. Deliver: blog post + schema markup + SEO checklist
**Output:** 2,500-word comparison article with FAQ schema, meta tags, and validation report
## Implementation Instructions
### Phase 1: Gather Requirements & Keyword Research
This skill supports two modes based on user input:
**Mode A: Keyword-Driven** (User provides specific target keyword)
**Mode B: Topic Expansion** (User provides general topic, needs keyword research)
#### Step 1: Detect Mode
Analyze user request to determine mode:
```
IF request contains specific keyword phrase in quotes → Mode A
Example: "Write post targeting 'healthy boundaries for empaths'"
ELSE IF request mentions specific long-tail keyword → Mode A
Example: "Write about best email marketing tools for Shopify stores"
ELSE IF request is general topic → Mode B
Example: "Write post about empath boundaries"
Example: "Create article on email marketing"
```
#### Step 2: Execute Mode-Specific Workflow
**MODE A: Keyword-Driven Workflow**
User has already identified target keyword. Proceed directly to validation:
1. Confirm keyword with user: "I'll optimize this post for '[keyword]'. Confirm?"
2. Collect remaining requirements:
- Target Audience
- Content Goal
- Author Details (name, credentials, bio, photo URL - critical for E-E-A-T)
- Word Count Target (1,500-3,000 words)
3. Continue to Phase 2 (Research & Pattern Selection)
**MODE B: Topic Expansion Workflow**
User needs keyword research assistance. Execute keyword research:
1. **Run keyword research script (with credential handling):**
The script automatically tries multiple credential methods in order:
1. Command line argument (`--api-key`)
2. Environment variable (`DATAFORSEO_API_KEY`)
3. Config file (`~/.dataforseo-skill/config.json`)
4. Fallback to heuristic mode (no API needed)
**IMPORTANT FOR CLAUDE CODE ENVIRONMENT:**
**Option A: Ask user for API key (if they want real data):**
```
Claude: "Would you like to use the DataForSEO API for real keyword data?
If yes, please provide your API key in format: login:password
If no, I'll use fallback mode with intelligent estimates."
IF user provides key:
python scripts/keyword_research.py "user topic" --limit 5 --format markdown --api-key "user_provided_key"
ELSE:
python scripts/keyword_research.py "user topic" --limit 5 --format markdown
```
**Option B: Use fallback mode directly (faster, no credentials needed):**
```bash
# Fallback mode works without any credentials
python scripts/keyword_research.py "user topic" --limit 5 --format markdown
```
**DO NOT use `--interactive` flag** - it doesn't work in Claude Code's non-TTY environment.
**Note:** The script automatically falls back to heuristic mode if:
- No credentials found
- API call fails (invalid credentials, rate limit, etc.)
- Script provides intelligent keyword suggestions without API
3. **Present options to user:**
Display top 3-5 keywords with metrics:
- Search volume (monthly searches)
- Keyword difficulty (0-100, lower = easier to rank)
- Relevance score (0-100, higher = better match)
Example output:
```
I've researched keywords for "empath boundaries". Top options:
1. healthy boundaries for empaths (Vol: 2,400, Diff: 45, Score: 95)
2. empath boundary setting tips (Vol: 1,200, Diff: 38, Score: 88)
3. how to set boundaries as an empath (Vol: 3,100, Diff: 52, Score: 92)
Which keyword would you like to target? (or type 'auto' for best match)
```
4. **Handle user selection:**
**Option 1: User selects specific keyword**
```
User: "Let's use #2"
→ Proceed with selected keyword
```
**Option 2: User requests auto-selection**
```
User: "auto" or "pick the best one"
→ Select highest relevance score
→ Inform user: "Auto-selected: [keyword] (best relevance score)"
```
5. **Collect remaining requirements** (same as Mode A)
6. **Continue to Phase 2**
#### Step 3: Validation & Optimization Notes
For **Mode B** keywords (researched via script):
- Note search volume in outline planning (high volume = more comprehensive content needed)
- Adjust word count based on keyword difficulty:
- Difficulty 0-30: 1,500-2,000 words sufficient
- Difficulty 31-60: 2,000-2,500 words recommended
- Difficulty 61-100: 2,500-3,000+ words required
#### Fallback Handling
If `scripts/keyword_research.py` fails or is unavailable:
1. Inform user: "Keyword research tool unavailable. Using heuristic analysis."
2. Generate 3-5 variations manually using common patterns:
- "best [topic]"
- "how to [topic]"
- "[topic] guide"
- "[topic] tips"
- "[topic] for beginners"
3. Present options with estimated competitiveness
4. Continue workflow normally
### Phase 2: Research and Pattern Selection
**Research Steps:**
1. Identify search intent: Informational, commercial, transactional, or navigational
2. Load `references/seo-checklist.md` → Extract keyword strategy and meta optimization tactics
3. Analyze top-ranking content patterns
4. Gather citation-worthy sources: statistics, studies, expert quotes
**Pattern Selection:**
Load `references/content-patterns.md` and select appropriate structure:
- **Ultimate Guide**: Comprehensive topics (2,000+ words)
- **How-To Guide**: Process-oriented content (1,500-2,500 words)
- **Comparison/Review**: Product comparisons (2,000-3,000 words)
- **Listicle**: Roundups and curated lists (1,000-2,500 words)
- **Data-Driven Research**: Original research posts (2,000-4,000 words)
### Phase 3: Create Outline
Generate structure including:
- SEO-optimized title (primary keyword within first 60 characters)
- Introduction with hook and primary keyword in first 100 words
- 4-8 H2 sections with keyword variations
- FAQ section (4-8 questions minimum)
- Conclusion with clear CTA
- Author bio section
Use `assets/blog-template.md` as structural reference.
### Phase 4: Write Draft
Load `references/eeat-guidelines.md` and apply E-E-A-T principles:
**Experience signals:**
- Include first-hand experiences, testing results, or case studies
- Use specific examples and real scenarios
- Add screenshots, data, or proof when applicable
**Expertise signals:**
- Cite authoritative sources with proper attribution
- Include expert quotes or interviews
- Reference recent studies and statistics (with dates)
- Use precise, accurate terminology
**Authoritativeness signals:**
- Link to authoritative external sources (2-4 per article)
- Build topical clusters with internal links (3-5 per article)
- Demonstrate comprehensive topic coverage
**Trustworthiness signals:**
- Add author bio with credentials
- Include last updated date
- Provide accurate, verifiable information
- Add disclosures where relevant (affiliate links, sponsorships)
**GEO Optimization:**
Load `references/geo-optimization.md` for AI citation formatting:
- Start sections with clear, quotable statements
- Use "According to [Source]" attribution format
- Include statistics with sources and dates
- Structure data in easily extractable formats (tables, lists)
- Provide direct, concise answers in FAQ (40-60 word paragraphs)
- Include "what, why, how" question variations
### Phase 5: Auto Internal Linking (NEW v2.2)
**Automated internal link discovery and insertion:**
1. **Discover existing content from configured sources:**
```bash
# Test content discovery first
python scripts/content_sources.py \
--sanity-project-id $SANITY_PROJECT_ID \
--local-content ./blog-posts
```
**Content source priority:**
1. Sanity CMS API (if `SANITY_PROJECT_ID` configured)
2. Local markdown directory (if `--local-content` provided)
3. Fallback to empty (no links inserted)
2. **Auto-insert internal links into draft:**
```bash
python scripts/auto_internal_linking.py /tmp/blog_draft.md \
--sanity-project-id $SANITY_PROJECT_ID \
--min-confidence 90 \
--max-links 5 \
--output /tmp/blog_draft_linked.md
```
3. **Link insertion process:**
The script automatically:
- Discovers existing blog posts from configured sources
- Analyzes relevance between draft and existing content
- Identifies high-confidence linking opportunities (≥90 relevance)
- Inserts markdown links for first keyword occurrence
- Avoids over-linking (max 5 links by default)
**Example output:**
```
✓ Found 50 existing pages for internal linking
✓ Found 8 total suggestions
→ 5 high-confidence (≥90)
✓ Successfully inserted 5 links:
1. Email marketing → /blog/email-marketing-guide (95)
2. Marketing automation → /blog/automation-best-practices (92)
3. Customer segmentation → /blog/segmentation-strategies (91)
4. Email campaigns → /blog/campaign-optimization (90)
5. ROI tracking → /blog/marketing-metrics (90)
```
4. **Configuration options:**
**Via command line:**
```bash
# Sanity CMS (recommended)
python scripts/auto_internal_linking.py draft.md \
--sanity-project-id your-project-id \
--sanity-dataset production
# Local markdown files
python scripts/auto_internal_linking.py draft.md \
--local-content ./blog-posts
# Adjust confidence threshold
python scripts/auto_internal_linking.py draft.md \
--local-content ./posts \
--min-confidence 85 # Lower threshold for more links
```
**Via environment variables:**
```bash
export SANITY_PROJECT_ID=your-project-id
export SANITY_DATASET=production
python scripts/auto_internal_linking.py draft.md
```
**Via config file:** `.seo-geo-config.json`
```json
{
"sanity": {
"project_id": "your-project-id",
"dataset": "production"
},
"internal_linking": {
"min_confidence_auto_insert": 90,
"max_links_per_post": 5
}
}
```
5. **Continue to Phase 6** (Image Generation) or **Phase 7** (Final Validation)
### Phase 6: Image Generation (NEW v2.2)
**Automated image generation and insertion using AI APIs:**
Generate professional blog post images automatically using Google Imagen or OpenAI DALL-E 3. The system extracts image placeholders, classifies image types, generates appropriate images, and inserts them into your draft.
**1. Add image placeholders to your draft (optional):**
During Phase 4 (drafting), add placeholders where you want images:
```markdown


```
**Note:** Featured/hero image is auto-generated if not present.
**2. Generate images:**
**Option A - OpenAI DALL-E 3 (easiest setup):**
```bash
export OPENAI_API_KEY=sk-...
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md \
--max-images 5
```
**Option B - Google Imagen (requires Google Cloud):**
```bash
export GOOGLE_API_KEY=...
export GOOGLE_PROJECT_ID=my-project
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md \
--max-images 5
```
**Option C - Use configuration file:**
```bash
# Configure in .seo-geo-config.json:
{
"image_generation": {
"enabled": true,
"google_api_key": "...",
"google_project_id": "...",
"openai_api_key": "sk-...",
"max_images_per_post": 5,
"output_dir": "./generated_images"
}
}
python scripts/image_generation.py /tmp/blog_draft.md \
--output /tmp/blog_draft_with_images.md
```
**3. Test extraction without API keys (dry-run):**
```bash
python scripts/image_generation.py /tmp/blog_draft.md --dry-run
# Output shows:
# - Number of images that would be generated
# - Image type and style classification
# - Alt text and context for each image
```
**How it works:**
1. **Extract Image Needs:**
- Finds all `` patterns
- Auto-adds featured/hero image if none exists
- Classifies image type (featured, section, diagram)
- Determines appropriate style (photorealistic, illustration, diagram)
2. **Generate Images:**
- Priority 1: Google Imagen ($0.02/image, $2000 startup credit)
- Priority 2: OpenAI DALL-E 3 ($0.04-$0.08/image, Microsoft credits)
- Optimized prompts for each style and image type
- Downloads and saves images locally
3. **Insert Into Draft:**
- Replaces `(placeholder)` with actual image paths
- Updates alt text for SEO
- Preserves markdown formatting
**Image Classification:**
- **Featured/Hero Images:** Photorealistic style, 1792x1024px
- Trigger: First image or auto-generated from title
- Example: "Professional email marketing dashboard"
- **Section Images:** Illustration style, 1024x1024px
- Trigger: Images within content sections
- Example: "Email list building strategy"
- **Diagrams/Infographics:** Technical diagram style, 1024x1024px
- Trigger: Keywords like "diagram", "flowchart", "workflow", "infographic"
- Example: "Email automation workflow diagram"
**Cost tracking:**
The script shows total generation cost and per-image pricing for budget management.
**Generated output structure:**
```
/tmp/blog_draft_with_images.md ← Updated draft with images
./generated_images/ ← Image directory
├── image_abc123.png ← Featured image
├── image_def456.png ← Section image 1
└── image_ghi789.png ← Diagram
```
### Phase 7: Final Validation and Auto-Fix
**Validation Protocol (ALWAYS EXECUTE):**
1. **Write draft to temporary file:**
```bash
# Save draft to /tmp/blog_draft.md
```
2. **Execute iterative validation with auto-fix:**
```bash
python scripts/iterative_validation.py /tmp/blog_draft.md \
--max-iterations 3 \
--target-score 80 \
--output /tmp/blog_draft_final.md
```
3. **Iterative validation process:**
The script automatically:
- Validates current draft state
- Auto-fixes common issues (FAQ, author bio, schema templates, title length)
- Re-validates after fixes
- Stops when: score ≥80 OR max 3 iterations OR no more auto-fixable issues
**Auto-fixable items:**
- Missing FAQ section → Generates 4-6 questions from H2 headings
- Missing author bio → Adds template (user fills details later)
- Short title (<50 chars) → Expands with year or descriptive phrases
- Missing schema → Adds BlogPosting and FAQPage templates
**Non-auto-fixable items** (require manual attention):
- Low word count → Note thin sections for expansion
- Missing internal/external links → Needs content research
- Missing images → Needs image sourcing or generation
- Low readability score → Needs content restructuring
4. **Interpret results:**
```
Final Score: 88/100
Fixes Applied (4):
✓ Added FAQ section with 6 questions
✓ Added author bio template (requires user completion)
✓ Expanded title: 'Tips' → 'Complete Tips Guide 2025'
✓ Added schema markup templates (requires completion)
✓ PASSED (8 checks): Title optimal, Word count good, FAQ present...
⚠ WARNINGS (3 items): Internal links low, Images needed...
```
- Score ≥80: Excellent, proceed to delivery
- Score 60-79: Review warnings, address critical ones
- Score <60: Fix FAILED checks manually, re-run validation
5. **Complete placeholders in auto-generated content:**
- **Author bio**: Replace `[Author Name]`, `[job title]`, `[X years]` with real details
- **Schema markup**: Fill in `[YYYY-MM-DD]`, `[Meta description]`, `[Featured image URL]`
- **FAQ answers**: Expand auto-generated summaries if needed
6. **Handle script failure:**
If script unavailable, use manual validation with `references/seo-checklist.md`:
- Primary keyword in title, H1, first 100 words, URL slug, meta description
- 2-3 H2 headings with keyword variations
- Internal links (3-5) and external authority links (2-4)
- Images with optimized alt text
- FAQ section with schema markup
- Author bio with credentials
- Meta title (50-60 chars) and description (145-155 chars)
7. **Deliver final package:**
- Complete blog post with auto-fixes applied (`/tmp/blog_draft_final.md`)
- Validation report showing score and fixes applied
- Schema markup code blocks (with placeholders to complete)
- SEO checklist with verification status
- Image suggestions with alt text
- Internal linking recommendations
## Resource Loading Strategy
### When to Load Each Reference
**Requirements Phase (Load if needed):**
- Execute `scripts/keyword_research.py` → When Mode B detected (topic expansion needs keyword research)
**Planning Phase (Always load):**
- Read `references/content-patterns.md` → Select appropriate pattern based on topic and search intent
**Research Phase (Load if needed):**
- Read `references/seo-checklist.md` → When conducting keyword research or meta optimization
- Read `references/geo-optimization.md` → When planning citation-worthy formatting
**Draft Phase (Load selectively):**
- Read `references/eeat-guidelines.md` → When writing sections requiring credibility signals
- Use `assets/blog-template.md` → As structural reference for section organization
**Validation Phase (Always execute):**
- Execute `scripts/validate_structure.py` → After completing draft
- Read `assets/structured-data-examples.json` → When generating schema markup
### Token Efficiency for Large Files
`references/content-patterns.md` is 758 lines. For targeted reading:
```bash
# Read only specific pattern instead of entire file
grep -A 100 "## Pattern 2: How-To Guide" references/content-patterns.md
```
This approach: ~400 tokens vs ~3,000 tokens for full file.
## Output Deliverables
Provide complete package:
1. Blog post in markdown (using `assets/blog-template.md` structure)
2. SEO checklist with verification status for each item
3. Schema markup code blocks (BlogPosting + FAQPage)
4. Image suggestions with optimized alt text
5. Internal linking recommendations with anchor text
6. Validation report from script execution
## Critical Requirements (What NOT to Do)
Avoid these quality-damaging practices:
- Thin content (<1,000 words for competitive topics)
- Keyword stuffing (maintain natural readability)
- Unverifiable claims or missing citations
- Missing author credibility (E-E-A-T critical for rankings)
- Poor mobile readability (short paragraphs required)
- Clickbait tactics (damages trustworthiness signals)
- Copying competitor content (use as pattern inspiration only)
- Skipping FAQ section (critical for GEO optimization)
- Missing schema markup (required for rich results)
- No author bio (damages E-E-A-T scoring)
## Quality Targets
Target these metrics for optimal performance:
- Readability score: 60-70 (Flesch Reading Ease)
- Keyword density: 1-2% for primary keyword
- Heading hierarchy: Proper H1 → H2 → H3 structure
- FAQ section: 4-8 questions with schema markup
- Internal links: 3-5 with descriptive anchor text
- External links: 2-4 to authoritative sources
- Images: 5-8 with optimized alt text
- Word count: 1,500-3,000 (adjust for competition)
- E-E-A-T signals: Author bio, citations, first-hand experience
- Schema markup: BlogPosting + FAQPage minimum
## Optimization Factors for Best Results
**Input Quality:**
- Specific topic details improve output precision
- Real author credentials significantly improve E-E-A-T scoring
- Existing case studies or data enhance content quality
- Clear target audience definition enables better targeting
**Process Optimization:**
- Request outline approval before full draft to ensure direction alignment
- Execute validation script to catch structural issues early
- Plan content refresh every 6-12 months for freshness signals
## Related Skills
- **blog-optimizer**: Improve existing posts (different workflow from creation)
- **content-repurposer**: Convert blog posts to other formats (separate use case)