mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-20 08:06:35 +03:00
feat: add seo-audit skill (#19)
* feat: add seo-audit skill Signed-off-by: Magnus Hedemark <magnus919@pm.me> * fix: remove host-specific port assumptions Signed-off-by: Magnus Hedemark <magnus919@pm.me> * fix: generalize seo examples Signed-off-by: Magnus Hedemark <magnus919@pm.me> * fix: anonymize site-specific seo examples Signed-off-by: Magnus Hedemark <magnus919@pm.me> * fix: generalize portable examples Signed-off-by: Magnus Hedemark <magnus919@pm.me> --------- Signed-off-by: Magnus Hedemark <magnus919@pm.me>
This commit is contained in:
@@ -138,6 +138,7 @@ When the user mentions these keywords, load the corresponding skill:
|
||||
| "c4-diagramming", "c4 diagramming" | [c4-diagramming](c4-diagramming/SKILL.md) |
|
||||
| "technology-radar", "technology radar" | [technology-radar](technology-radar/SKILL.md) |
|
||||
| "verification-methodology", "verification methodology" | [verification-methodology](verification-methodology/SKILL.md) |
|
||||
| "seo-audit", "seo audit" | [seo-audit](seo-audit/SKILL.md) |
|
||||
## Use-When Sections
|
||||
|
||||
Every skill description must identify when to load it. Skills with meaningful overlap should also include a `## When not to use` section naming the nearest alternative or prerequisite. Keep these sections trigger-oriented and concise; implementation details belong in references.
|
||||
|
||||
@@ -207,6 +207,10 @@ Turn an open question into a bounded, evidence-led investigation rather than a p
|
||||
|
||||
Give authorized teams a disciplined way to identify and prioritize security risks without mistaking a checklist for a security guarantee.
|
||||
|
||||
### [seo-audit](seo-audit/SKILL.md)
|
||||
|
||||
Identify search-discoverability problems through evidence, prioritize the work, and distinguish technical defects from content opportunities.
|
||||
|
||||
### [site-reliability-engineering](site-reliability-engineering/SKILL.md)
|
||||
|
||||
Build practical reliability practices around the work teams actually perform: measurable service objectives, useful alerts, incident response, and learning-oriented follow-up.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Seo Audit
|
||||
|
||||
Identify search-discoverability problems through evidence, prioritize the work, and distinguish technical defects from content opportunities.
|
||||
|
||||
## Why Install This Skill
|
||||
|
||||
Identify search-discoverability problems through evidence, prioritize the work, and distinguish technical defects from content opportunities. It preserves a practical method, local reference material, and reusable templates so an agent can do more than produce a generic answer.
|
||||
|
||||
Use it when the work needs a repeatable process and an inspectable result. It is portable across Agent Skills-compatible clients and does not require a profile system or a particular task orchestrator.
|
||||
|
||||
## What You Get
|
||||
|
||||
| Path | What it provides |
|
||||
|---|---|
|
||||
| `SKILL.md` | Trigger conditions, workflow, and guidance for loading deeper resources. |
|
||||
| `references/` | Reference material: `aeo-methodology.md`, `content-strategy-seo.md`, `ghost-metadata.md`, `onpage-seo.md`, `schema-markup.md`, `technical-seo.md` |
|
||||
| `assets/` | Assets: `audit-report-template.md` |
|
||||
|
||||
## Quick Start
|
||||
|
||||
Start with the technical, on-page, or schema reference that matches the page or site under review.
|
||||
|
||||
Install or expose this directory using your agent's standard Agent Skills loading mechanism, then ask for work that matches the triggers below.
|
||||
|
||||
## Triggers
|
||||
|
||||
- Audit websites and pages for technical SEO, on-page SEO, schema markup, content discoverability, and answer-engine readiness. Use when prioritizing search visibility improvements.
|
||||
- Requests involving the method, deliverables, or review process described in `SKILL.md`.
|
||||
- Work where a reusable template or reference from this skill would reduce avoidable mistakes.
|
||||
|
||||
## Requirements
|
||||
|
||||
Requires access to the site or page being audited. Platform-specific references are optional and must be applied only when relevant.
|
||||
|
||||
## Source and maintenance
|
||||
|
||||
This skill was extracted from [`magnus919/hermes-profiles`](https://github.com/magnus919/hermes-profiles) at commit [`867a555`](https://github.com/magnus919/hermes-profiles/commit/867a555). The portable methodology was retained; Hermes-specific profile, orchestration, and memory assumptions were removed.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
name: seo-audit
|
||||
description: Audit websites and pages for technical SEO, on-page SEO, schema markup, content discoverability, and answer-engine readiness. Use when prioritizing search visibility improvements.
|
||||
license: MIT
|
||||
compatibility: Requires access to the site or page being audited. Platform-specific references are optional and must be applied only when relevant.
|
||||
metadata:
|
||||
source_repo: https://github.com/magnus919/hermes-profiles
|
||||
source_commit: 867a555
|
||||
---
|
||||
|
||||
|
||||
# SEO Audit
|
||||
|
||||
Full-spectrum audit for sites, articles, and content strategies. Covers both traditional SEO and Answer Engine Optimization (AEO/GEO) — the practice of structuring content so LLMs and AI answer engines (ChatGPT, Perplexity, Gemini, Claude, Google AI Overviews) extract and cite it.
|
||||
|
||||
Use `assets/audit-report-template.md` for a portable audit deliverable. If the host workflow uses artifact pyramids, that structure can be an optional presentation format rather than a prerequisite.
|
||||
|
||||
|
||||
## SEO + AEO Audit: [Site/Page URL]
|
||||
|
||||
**Overall Health:** [Good / Fair / Poor]
|
||||
**Score:** [N/100]
|
||||
|
||||
### SEO Priority Findings
|
||||
1. [Critical] → [Action]
|
||||
|
||||
### AEO Priority Findings
|
||||
1. [Critical] → [Action]
|
||||
|
||||
### Quick Wins
|
||||
1. [Low effort, high impact] → [Action]
|
||||
|
||||
### Verdict
|
||||
[One paragraph summarizing the single most important thing to fix and expected impact.]
|
||||
```
|
||||
|
||||
## Contents
|
||||
|
||||
| File | What it covers |
|
||||
|------|----------------|
|
||||
| `references/technical-seo.md` | Crawlability, indexability, robots.txt, sitemaps, page speed, Core Web Vitals, mobile-friendliness, HTTPS, canonical URLs, hreflang |
|
||||
| `references/onpage-seo.md` | Title tags, meta descriptions, heading hierarchy, keyword placement, content quality, internal linking, image optimization |
|
||||
| `references/schema-markup.md` | Schema.org types (TechArticle, FAQPage, HowTo, Article, BlogPosting, BreadcrumbList, Organization), JSON-LD format, Google rich results, validation |
|
||||
| `references/content-strategy-seo.md` | Topic clusters, pillar pages, keyword research, gap analysis, SERP feature targeting, topical authority |
|
||||
| `references/ghost-metadata.md` | Ghost CMS metadata fields (meta_title, meta_description, custom_excerpt), social media cards (OG, Twitter), code-injected schema (JSON-LD, FAQPage, TechArticle, @graph), per-post and site-wide injection, validation |
|
||||
| `references/aeo-methodology.md` | Answer Engine Optimization — LLM RAG pipeline, answer-first content architecture, AEO-specific schema (FAQPage 3.2× boost), Ethan Smith/Graphite frameworks, question clusters, llms.txt, content negotiation, measurement |
|
||||
| `assets/audit-report-template.md` | Blank report scaffold for new audits |
|
||||
|
||||
## When to Use
|
||||
|
||||
Load this skill when:
|
||||
- Auditing a site for technical SEO issues
|
||||
- Optimizing a new article for search and AI citation before publication
|
||||
- Validating structured data on an existing page
|
||||
- Completing Ghost CMS metadata (meta, social cards, schema injection) before publish
|
||||
- Running an AEO readiness audit (llms.txt, content negotiation, question-cluster coverage)
|
||||
- Developing a content strategy with SEO + AEO in parallel
|
||||
- Diagnosing why a site or page isn't performing in search or AI citation
|
||||
|
||||
Do NOT load when:
|
||||
- Only mechanical content fixes are needed; use the host agent's copy-editing workflow.
|
||||
- Only writing is needed; use the host agent's writing workflow.
|
||||
|
||||
## Portability
|
||||
|
||||
This skill is intentionally host-neutral. Use your agent's normal mechanisms to load the references, templates, and scripts listed here. Do not assume a particular profile system, task orchestrator, memory service, or response-handoff format.
|
||||
@@ -0,0 +1,76 @@
|
||||
# SEO Audit Report Template
|
||||
|
||||
Scaffold for new SEO audit projects. Copy this into your pyramid root.
|
||||
|
||||
```markdown
|
||||
# SEO Audit: [Site/Page URL]
|
||||
|
||||
**Audit date:** YYYY-MM-DD
|
||||
**Auditor:** seo-specialist profile
|
||||
**Scope:** [Full site / Single page / Content strategy]
|
||||
|
||||
---
|
||||
|
||||
## L1 Summary
|
||||
|
||||
### Overall Health: [Good / Fair / Poor]
|
||||
### Score: [N/100]
|
||||
|
||||
### Priority Findings
|
||||
1. [Critical] → [Action]
|
||||
2. [Critical] → [Action]
|
||||
|
||||
### Moderate Findings
|
||||
1. [Important] → [Action]
|
||||
|
||||
### Quick Wins
|
||||
1. [Low effort, high impact] → [Action]
|
||||
|
||||
---
|
||||
|
||||
## L2 Analysis Files
|
||||
|
||||
### Technical SEO
|
||||
- Crawlability and indexability
|
||||
- Page speed / Core Web Vitals
|
||||
- Mobile-friendliness
|
||||
- HTTPS and security
|
||||
- Canonical URLs and hreflang
|
||||
- Sitemap and robots.txt
|
||||
|
||||
### On-Page SEO
|
||||
- Title tags and meta descriptions
|
||||
- Heading structure
|
||||
- Keyword usage
|
||||
- Content quality and length
|
||||
- Internal linking
|
||||
- Image optimization
|
||||
- URL structure
|
||||
|
||||
### Schema Validation
|
||||
- JSON-LD structure
|
||||
- Schema.org types used
|
||||
- Rich result eligibility
|
||||
- Validation results
|
||||
|
||||
### Content Gap Analysis
|
||||
- Target keywords
|
||||
- Current rankings
|
||||
- Competitor analysis
|
||||
- Gap identification
|
||||
- Priority recommendations
|
||||
|
||||
---
|
||||
|
||||
## L3 Dossiers
|
||||
|
||||
### Raw Data
|
||||
- Full crawl results
|
||||
- Schema validation output
|
||||
- Keyword research data
|
||||
- Competitor SERP data
|
||||
|
||||
### Methodology Notes
|
||||
- Tools used
|
||||
- Assumptions and limitations
|
||||
- Data collection dates
|
||||
@@ -0,0 +1,177 @@
|
||||
# Answer Engine Optimization (AEO) Methodology
|
||||
|
||||
AEO (also called GEO — Generative Engine Optimization) is the practice of structuring content so AI-powered answer engines (ChatGPT, Perplexity, Gemini, Claude, Google AI Overviews) extract, cite, and surface it in their generated responses.
|
||||
|
||||
**Core insight:** ChatGPT traffic converts 6× better than Google search (Ethan Smith, Graphite). Content that ranks in Google is 3× more likely to appear in LLM citations. SEO and AEO are complementary — the SEO foundation feeds AEO performance.
|
||||
|
||||
## How LLMs Surface Content
|
||||
|
||||
Modern LLMs with web access use Retrieval-Augmented Generation (RAG):
|
||||
|
||||
1. **Query expansion** — User prompt is expanded into related sub-queries
|
||||
2. **Retrieval** — Web search or vector DB finds candidate pages
|
||||
3. **Re-ranking** — Chunks scored by relevance to query
|
||||
4. **Synthesis** — LLM generates answer grounded in top chunks
|
||||
5. **Citation** — Sources appended as footnotes or inline links
|
||||
|
||||
### Key Signals for Citation Selection
|
||||
|
||||
**Semantic relevance** — content must match semantic meaning, not just keywords. Named entities (people, products, brands, places) boost relevance scoring.
|
||||
|
||||
**Answer placement** — First 1-2 sentences of a section are the most extractable. Pages with clean heading hierarchy earn 2.8× higher citation rates (AirOps 2026).
|
||||
|
||||
**Authority** — 96% of AI Overview citations come from sources Google already trusts (Ziptie.dev). E-E-A-T functions as a binary gatekeeper, not just a ranking signal.
|
||||
|
||||
**Freshness** — Pages accessible to GPTBot, ClaudeBot, PerplexityBot. AI Overviews favors recently crawled content.
|
||||
|
||||
**FAQPage schema** — Pages with FAQPage schema appear in AI Overviews 3.2× more often (SearchAtlas data).
|
||||
|
||||
## Content Structure for AEO
|
||||
|
||||
### Answer-First Architecture
|
||||
|
||||
Every section should follow the inverted pyramid:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ Direct answer (first 1-2 sentences) │ ← Most extractable
|
||||
├──────────────────────────────────┤
|
||||
│ Supporting details / evidence │ ← Reinforces citation confidence
|
||||
├──────────────────────────────────┤
|
||||
│ Background / context │ ← For human readers
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Structural Requirements
|
||||
|
||||
- **One clear H1** aligned with the primary topic
|
||||
- **Question-based H2s** — Write headings as standalone user questions ("How does X work?")
|
||||
- **Answer in the opening sentence** — Every section's first sentence directly answers the heading
|
||||
- **Short paragraphs** — 2-4 sentences max
|
||||
- **Consistent terminology** — One term per concept; don't rotate synonyms (helps entity recognition)
|
||||
- **TL;DR / Summary block** — Quick-extractable answer at the top of the article
|
||||
- **FAQ sections** — Self-contained Q&A pairs matching how users query AI assistants
|
||||
- **Lists and tables** — LLMs efficiently extract structured data from ordered/unordered lists
|
||||
- **Quote-worthy claims** — Key numbers in the first sentence of their paragraph; specific, confident, unhedged language
|
||||
|
||||
### What NOT to Do
|
||||
|
||||
- Long intros / historical context before the answer
|
||||
- Delaying the answer to increase time-on-page (penalized by LLMs)
|
||||
- Creative/metaphorical headings ("The Dance of Algorithms")
|
||||
- Redundant restatements of the same point
|
||||
- Relying solely on schema to compensate for vague content
|
||||
|
||||
## AEO-Specific Structured Data
|
||||
|
||||
| Schema Type | AEO Impact | Priority |
|
||||
|-------------|-----------|----------|
|
||||
| **FAQPage** | 3.2× more citations in AI Overviews. LLMs directly extract Q&A pairs. | Highest |
|
||||
| **HowTo** | Step-by-step instructions extracted for procedural queries | High |
|
||||
| **Article / TechArticle** | Signals content type, authorship, publication date | Required |
|
||||
| **Organization** | Establishes publisher identity and authority | Required |
|
||||
| **Person** | Author credentials and authority signals | High |
|
||||
| **BreadcrumbList** | Helps LLMs understand site hierarchy | Medium |
|
||||
|
||||
**Key rules:**
|
||||
- JSON-LD is the preferred format
|
||||
- Schema must match visible content exactly (misleading schema damages trust)
|
||||
- Pages using 3+ relevant schema types show ~13% higher citation likelihood (AirOps)
|
||||
- FAQPage schema provides compounding benefits when paired with FAQ formatting in visible content
|
||||
|
||||
## Ethan Smith / Graphite's AEO Framework
|
||||
|
||||
### The 5% Principle
|
||||
Only ~5% of SEO/AEO strategies drive outsized results. Process: Generate Ideas → Test & Evaluate → Reproduce Results.
|
||||
|
||||
### High-Impact AEO Tactics (the 5%)
|
||||
1. **New AEO landing pages** — Create pages for topics you don't cover
|
||||
2. **Content enhancement** — Fill answer gaps on existing pages
|
||||
3. **Citation optimization** — Get mentioned on the most-cited URLs for target topics
|
||||
|
||||
### Biggest Waste of Time
|
||||
Technical AEO (page speed, crawl errors) is low-impact. Priorities: content quality > question coverage > authority > technical tweaks.
|
||||
|
||||
### AEO Topics (Not Keywords)
|
||||
An AEO topic = a cluster of questions targeting a single page. Questions have head, mid-tail, and long-tail varieties. Focus on "Product Questions" — those where answers suggest products or brands.
|
||||
|
||||
### Owned vs. Earned
|
||||
- **Owned** (SEO-like): Directly ranking your page — more effective for specific, product-oriented questions
|
||||
- **Earned**: Being cited as a source within the LLM's answer — more critical for general, high-level questions
|
||||
|
||||
### The 7-Step AEO Playbook
|
||||
1. Identify target AEO topics (question clusters)
|
||||
2. Audit current content for answer gaps
|
||||
3. Create or enhance pages with answer-first structure
|
||||
4. Add structured data (FAQPage, Article, etc.)
|
||||
5. Build off-site authority (Reddit, YouTube, guest content)
|
||||
6. Measure citation rate and iterate
|
||||
7. Scale what works, kill what doesn't
|
||||
|
||||
## LLM-Friendly Content Formats
|
||||
|
||||
### llms.txt
|
||||
A markdown file at the site root providing LLMs with background, guidance, and links. Functions as a foundational AEO element — provides curated context for LLMs, reduces hallucinations, and controls how your site is understood.
|
||||
|
||||
**Structure:**
|
||||
```markdown
|
||||
# Site Name
|
||||
> Brief description
|
||||
|
||||
## Pages
|
||||
- [Page Title](URL)
|
||||
|
||||
## Optional
|
||||
- [Full content](llms-full.txt)
|
||||
```
|
||||
|
||||
### Content Negotiation (Accept: text/markdown)
|
||||
Serve Markdown to LLM agents and HTML to browsers. The agent sends `Accept: text/markdown` in the HTTP header; the server returns clean Markdown. Standards-compliant — no separate URL needed.
|
||||
|
||||
**Hugo:** Already implemented on example.com — custom output format renders pages as Markdown. Serve via Hugo's built-in output format routing.
|
||||
|
||||
**Ghost:** Needs a reverse proxy (Nginx/Cloudflare Worker) or Ghost API-based solution. Ghost doesn't natively support content negotiation.
|
||||
|
||||
### Robots.txt for AI Crawlers
|
||||
Allow GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Applebot-Extended:
|
||||
```txt
|
||||
User-agent: GPTBot
|
||||
Allow: /
|
||||
|
||||
User-agent: ClaudeBot
|
||||
Allow: /
|
||||
|
||||
User-agent: PerplexityBot
|
||||
Allow: /
|
||||
|
||||
User-agent: Google-Extended
|
||||
Allow: /
|
||||
|
||||
User-agent: Applebot-Extended
|
||||
Allow: /
|
||||
```
|
||||
|
||||
## Measurement
|
||||
|
||||
### Core AEO Metrics
|
||||
| Metric | What It Measures | How |
|
||||
|--------|-----------------|-----|
|
||||
| Citation Rate | How often AI cites your content | Manual LLM queries; tools like LLMrefs, AirOps Insights |
|
||||
| AI Share of Voice | Brand mention frequency vs. competitors | Same prompt set across multiple LLMs |
|
||||
| Query Coverage | Range of questions where content appears | Expand query into sub-questions; test each |
|
||||
| AI Referral Traffic | Clicks from ChatGPT, Perplexity, etc. | GA4 source/medium reports |
|
||||
| AI Overview Appearances | Visibility in Google AI Overviews | GSC → Search Appearance → AI Overviews |
|
||||
| AEO Readiness Score | Site-level technical AEO readiness | AEOprobe, ansly scanners |
|
||||
|
||||
### Cadence
|
||||
- **Weekly:** Test 5-10 key prompts per site against major LLMs
|
||||
- **Monthly:** Citation rate audit, brand mention accuracy check
|
||||
- **Quarterly:** Full AEO audit (structure, schema, llms.txt, crawlability)
|
||||
|
||||
### Key References
|
||||
- Ethan Smith / Graphite: graphite.io/five-percent/aeo-is-the-new-seo
|
||||
- Lenny's Podcast: "The ultimate guide to AEO" (Sept 2025)
|
||||
- AirOps 2026 State of AI Search
|
||||
- SearchAtlas: FAQPage schema → 3.2× AI Overview citations
|
||||
- Ziptie.dev: 96% of AI Overviews cite already-trusted sources
|
||||
- HubSpot: Page with 85 AI citations had only 1 backlink
|
||||
@@ -0,0 +1,142 @@
|
||||
# Content Strategy SEO Reference
|
||||
|
||||
Content strategy SEO ensures that what you write positions you to be discovered for the queries your audience actually searches for.
|
||||
|
||||
## Topic Clusters & Pillar Pages
|
||||
|
||||
The modern SEO content architecture replaces the old model of writing individual articles about individual keywords. Instead, content is organized into **topic clusters** centered on **pillar pages**.
|
||||
|
||||
### How It Works
|
||||
|
||||
- **Pillar page:** A comprehensive, long-form guide to a broad topic (e.g., "The Complete Guide to AI Agent Memory Systems"). It covers the topic broadly and links out to cluster content.
|
||||
- **Cluster content:** Specific articles that dive deep into sub-topics (e.g., "What is a Vector Database?", "How RAG Works", "GraphRAG vs Vector Search"). Each cluster article links BACK to the pillar page.
|
||||
- **Internal linking:** Cluster → pillar (always). Pillar → cluster (when relevant).
|
||||
|
||||
### Why It Works
|
||||
|
||||
- **Topical authority:** A group of pages all linking to each other around a common topic signals deep expertise to search engines
|
||||
- **SERP dominance:** Instead of competing for one keyword, you compete for an entire topic area
|
||||
- **User experience:** Readers naturally flow from intro content (pillar) to deep dives (clusters)
|
||||
|
||||
### Applying to Platform-specific implementation notes
|
||||
|
||||
**example.com — Example clusters:**
|
||||
- Pillar: "AI Agent Memory Systems"
|
||||
- Clusters: "Vector Databases for Agent Memory," "Knowledge Graphs vs Vector Search," "a content inventory Thought-Graph Architecture," "What is GraphRAG?"
|
||||
|
||||
**example.com — Example clusters:**
|
||||
- Pillar: "Enterprise AI Agent Deployment"
|
||||
- Clusters: "RAG at Scale: Lessons from Production," "AI Agent Orchestration," "Security Considerations for Enterprise AI," "Cost Optimization for LLM Inference"
|
||||
|
||||
## Keyword Research
|
||||
|
||||
### Process
|
||||
1. **Identify seed keywords** — the 3-5 core terms that define your site's domain
|
||||
2. **Expand via SERP analysis** — search each seed keyword and analyze the "People also ask" box, related searches at page bottom, and the top-ranking pages' headlines
|
||||
3. **Identify question-based queries** — "how does X work", "what is Y", "why Z matters" — these are excellent for featured snippet opportunities
|
||||
4. **Analyze search intent** — is the query informational (learning), navigational (finding a specific site), commercial (comparing options), or transactional (buying)? Match your content type to intent.
|
||||
5. **Assess competition** — are the top 10 results thin blog posts or deep authoritative guides? If the top results are weak, there's an opportunity.
|
||||
|
||||
### Keyword Mapping
|
||||
|
||||
Map each article to 1 primary keyword and 2-5 secondary/related keywords:
|
||||
|
||||
```
|
||||
Article: "The Artifact Pyramid: Progressive Disclosure for Agent Outputs"
|
||||
Primary: "artifact pyramid"
|
||||
Secondary: "progressive disclosure AI", "multi-agent output structure",
|
||||
"agent collaboration format", "research output pyramid"
|
||||
```
|
||||
|
||||
### Tools
|
||||
- Google Search Console (what queries your site already ranks for)
|
||||
- Google "People also ask" / related searches (free, authoritative)
|
||||
- AnswerThePublic (question-based query discovery)
|
||||
- Ahrefs / Semrush (paid — comprehensive keyword data)
|
||||
|
||||
## SERP Feature Targeting
|
||||
|
||||
Target specific SERP features by structuring content appropriately:
|
||||
|
||||
| SERP Feature | Best for | Content Structure |
|
||||
|-------------|----------|-------------------|
|
||||
| **Featured Snippet (Paragraph)** | "What is X" questions | Direct answer in first paragraph after H2. 40-50 words. |
|
||||
| **Featured Snippet (List)** | "Steps to X", "Types of X" | Numbered or bulleted list in the content. |
|
||||
| **Featured Snippet (Table)** | Comparisons, specifications | HTML table with clear headers and data. |
|
||||
| **FAQ Rich Result** | Multiple related questions | FAQPage schema with 2+ Q&A pairs visible in content. |
|
||||
| **HowTo Rich Result** | Tutorials, guides | HowTo schema with numbered steps. |
|
||||
| **People Also Ask** | Question-based queries | Address each question in its own H2 section. |
|
||||
| **Knowledge Panel** | Brand/organization queries | Organization schema, Wikipedia entry, verified social profiles. |
|
||||
|
||||
## Content Gap Analysis
|
||||
|
||||
### Process
|
||||
1. **Identify your target keywords** (the terms you WANT to rank for)
|
||||
2. **Check your current rankings** (do you already have content for these?)
|
||||
3. **Analyze top 10 results** for each keyword:
|
||||
- What content format are they using? (listicle, guide, video, tool)
|
||||
- How long is the content?
|
||||
- What angle do they take?
|
||||
- What's missing from their coverage?
|
||||
4. **Identify gaps:** Topics where your site has no content, or where your content is weaker than competitors'
|
||||
5. **Prioritize:** Volume × difficulty × relevance — focus on high-volume gaps that you can credibly fill
|
||||
|
||||
### Gap Types
|
||||
- **Missing topic:** No content exists on your site for a search-worthy topic
|
||||
- **Thin content:** Content exists but is significantly weaker than competitors'
|
||||
- **Outdated content:** Content exists but is no longer accurate or current
|
||||
- **Format gap:** Competitors rank with a format you haven't used (e.g., video, interactive tool, data study)
|
||||
|
||||
## Topical Authority
|
||||
|
||||
Topical authority is built over time by publishing a breadth and depth of content on a subject. It's the most defensible SEO strategy because it can't be replicated quickly.
|
||||
|
||||
### Building Topical Authority
|
||||
1. **Publish the pillar page first** — broad, comprehensive, definitive
|
||||
2. **Publish cluster content regularly** — 2-3 sub-topic articles per month
|
||||
3. **Interlink systematically** — every cluster article links to the pillar; the pillar links to clusters
|
||||
4. **Refresh content** — update pillar pages annually, cluster content as needed
|
||||
5. **Expand scope** — once you've covered the core topic, expand to adjacent topics
|
||||
|
||||
### Signals of Topical Authority
|
||||
- Your content ranks for multiple related keywords
|
||||
- Your content appears in "People also ask" for the topic
|
||||
- Other sites link to your content as a reference
|
||||
- Your content is cited in academic or industry publications
|
||||
|
||||
## Platform-specific implementation notes — SEO Opportunity Assessment
|
||||
|
||||
| Site | Domain Authority | Primary Keyword Focus | Largest Gap |
|
||||
|------|-----------------|----------------------|-------------|
|
||||
| example.com | Low (newer personal blog) | AI philosophy, neurodiversity, engineering | Few internal links between related posts; no topic cluster structure |
|
||||
| example.com | Low (newer enterprise AI blog) | Enterprise AI strategy, agentic AI | Very new — needs pillar pages and cluster strategy from the start |
|
||||
| example.org | Very low (community site) | Mesh networking, MeshCore, RDUMesh | Local SEO for Raleigh/Durham; community resource queries |
|
||||
| example.net | Minimal | Southeast mesh networking | Mostly informational — just needs proper on-page SEO |
|
||||
|
||||
### Recommended Actions by Site
|
||||
|
||||
**example.com:**
|
||||
- Implement topic clusters retroactively (group existing posts into 3-4 clusters with pillar pages)
|
||||
- Ensure every post links to 2-3 other posts
|
||||
- Add FAQPage schema to posts that answer multiple questions
|
||||
- Optimize for "People also ask" by structuring content around questions
|
||||
|
||||
**example.com:**
|
||||
- Plan pillar pages first before creating more isolated content
|
||||
- Target question-based keywords for featured snippet opportunities
|
||||
- Implement TechArticle schema on all technical posts
|
||||
- Focus on long-tail, low-competition keywords in the short term
|
||||
|
||||
**example.org:**
|
||||
- Local SEO: "mesh network Raleigh," "MeshCore North Carolina"
|
||||
- Community-Q&A content for FAQ rich results
|
||||
- Event pages for meetup/community gathering SEO
|
||||
|
||||
## Content Calendar
|
||||
|
||||
SEO content strategy produces a **ranked list** of content opportunities, not a dated calendar. Editorial schedules vary; prioritize by evidence rather than a fixed calendar. Prioritize by:
|
||||
|
||||
1. **Search volume × relevance** — How many searches × how well it fits the site
|
||||
2. **Competition gap** — How much better can we be than the current top results?
|
||||
3. **Ease of creation** — Does the research already exist in the vault or is it a new domain?
|
||||
4. **Pillar dependency** — Should this be created before or after the pillar page?
|
||||
@@ -0,0 +1,204 @@
|
||||
# Ghost CMS Metadata & Schema Completion
|
||||
|
||||
For Ghost CMS sites (example.com, example.org, example.net), the SEO specialist is responsible for completing all metadata on every published or draft article. This covers three distinct layers: Ghost CMS metadata fields, social media cards, and code-injected structured data.
|
||||
|
||||
## Layer 1: Ghost CMS Metadata Fields
|
||||
|
||||
Every Ghost post and page has a set of metadata fields in the post settings panel (or settable via the Ghost Admin API / ghost-cli). These must be filled for every article.
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Required | Purpose | Best Practice |
|
||||
|-------|----------|---------|---------------|
|
||||
| **Meta Title** | Always | Overrides the post title for SEO. Controls the `<title>` tag. | 50-60 chars, primary keyword front-loaded. If not set, Ghost uses the post title (which may be too long or lack keyword focus). |
|
||||
| **Meta Description** | Always | Overrides excerpt for SEO. Controls the meta description tag. | 150-160 chars, includes primary keyword + CTA, reads naturally. |
|
||||
| **Custom Excerpt** | Always | Used in card previews, RSS feeds, and as fallback for meta description. | 1-2 sentences capturing the article's core argument. Shorter than meta description (~120 chars). NOT the same as meta description — serves different contexts (card previews, not SERPs). |
|
||||
| **OG Title** | Recommended | Overrides the title for social sharing (Facebook, LinkedIn, Discord). | Defaults to meta title. Only needed if the social version should differ. |
|
||||
| **OG Description** | Recommended | Overrides the description for social sharing. | Defaults to meta description. Only needed if the social version should differ. |
|
||||
| **OG Image** | Always | The image that appears in social card previews. | Should be the article's feature/cover image. If not set, Ghost uses the feature image from the post. Set explicitly to ensure correct crop and fallback. |
|
||||
| **Twitter Title** | Recommended | Overrides the title for Twitter/X card previews. | Defaults to OG title. Only needed if the Twitter version should differ. |
|
||||
| **Twitter Description** | Recommended | Overrides the description for Twitter/X. | Defaults to OG description. |
|
||||
| **Twitter Image** | Recommended | Overrides the image for Twitter/X. | Defaults to OG image. Twitter's card crop differs from OG — set explicitly if the feature image crop doesn't work well as a square. |
|
||||
| **Canonical URL** | As needed | Overrides the canonical URL. | Only needed if the post is syndicated or republished from another source. Ghost auto-generates self-referencing canonicals. |
|
||||
| **Slug** | As needed | URL path. | Set before publish. Never change after publish without a 301 redirect. |
|
||||
|
||||
### Setting via ghost-cli
|
||||
|
||||
The `ghost-cli` tool has a `meta set` command for individual fields:
|
||||
|
||||
```bash
|
||||
# Set meta title and description
|
||||
ghost-cli --site example meta set <slug> \
|
||||
--meta-title "Primary Keyword Context | Groktopus" \
|
||||
--meta-description "150-160 char summary with keyword and call to action."
|
||||
|
||||
# Set OG and Twitter fields
|
||||
ghost-cli --site example meta set <slug> \
|
||||
--og-title "Optional: different from meta title" \
|
||||
--og-description "Optional: different from meta description" \
|
||||
--twitter-title "Optional: different from OG title"
|
||||
```
|
||||
|
||||
### Setting via Ghost Admin API
|
||||
|
||||
For bulk operations or automation, use the Admin API directly. The key fields in the post object are:
|
||||
|
||||
```json
|
||||
{
|
||||
"posts": [{
|
||||
"id": "post-id",
|
||||
"meta_title": "SEO Title",
|
||||
"meta_description": "SEO Description",
|
||||
"custom_excerpt": "Brief excerpt for cards",
|
||||
"og_image": "https://example.com/image.jpg",
|
||||
"og_title": "Social Title",
|
||||
"og_description": "Social Description",
|
||||
"twitter_image": "https://example.com/twitter-image.jpg",
|
||||
"twitter_title": "Twitter Title",
|
||||
"twitter_description": "Twitter Description",
|
||||
"canonical_url": null,
|
||||
"codeinjection_head": "<script type=\"application/ld+json\">...</script>",
|
||||
"codeinjection_foot": ""
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** When updating a post via PUT, you must include `updated_at` from the current post data — Ghost uses it for optimistic locking. Always fetch first, modify, then PUT.
|
||||
|
||||
## Layer 2: Social Media Cards
|
||||
|
||||
Social media cards control what appears when an article is shared on Facebook, LinkedIn, Discord, Twitter/X, Slack, and other platforms.
|
||||
|
||||
### How Ghost Generates Cards
|
||||
|
||||
Ghost automatically generates Open Graph and Twitter Card meta tags from the post's metadata fields:
|
||||
|
||||
```html
|
||||
<meta property="og:site_name" content="Groktopus">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="[OG Title or Meta Title or Post Title]">
|
||||
<meta property="og:description" content="[OG Description or Meta Description or Excerpt]">
|
||||
<meta property="og:image" content="[OG Image or Feature Image]">
|
||||
<meta property="og:url" content="[Post URL]">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="[Twitter Title or OG Title or Meta Title]">
|
||||
<meta name="twitter:description" content="[Twitter Description or OG Description or Meta Description]">
|
||||
<meta name="twitter:image" content="[Twitter Image or OG Image or Feature Image]">
|
||||
<meta name="twitter:site" content="@example">
|
||||
<meta name="twitter:creator" content="@example">
|
||||
```
|
||||
|
||||
### Fallback Chain
|
||||
|
||||
- **OG Title:** OG Title → Meta Title → Post Title
|
||||
- **OG Description:** OG Description → Meta Description → Custom Excerpt
|
||||
- **OG Image:** OG Image → Feature Image
|
||||
- **Twitter Title:** Twitter Title → OG Title → Meta Title → Post Title
|
||||
- **Twitter Image:** Twitter Image → OG Image → Feature Image
|
||||
|
||||
### Verification
|
||||
|
||||
```bash
|
||||
# Check what tags are being emitted
|
||||
curl -s https://example.com/<slug>/ | grep -E 'og:|twitter:'
|
||||
|
||||
# Test with validators
|
||||
# Facebook: https://developers.facebook.com/tools/debug/
|
||||
# Twitter: https://cards-dev.twitter.com/validator
|
||||
# LinkedIn: https://www.linkedin.com/post-inspector/
|
||||
```
|
||||
|
||||
## Layer 3: Code-Injected Schema
|
||||
|
||||
Ghost CMS auto-generates basic Article/BlogPosting schema, but custom schema types (TechArticle, FAQPage, HowTo, Organization with areaServed) must be code-injected.
|
||||
|
||||
### Injection Points in Ghost
|
||||
|
||||
| Location | Scope | Method |
|
||||
|----------|-------|--------|
|
||||
| **Site-wide** (`ghost_head`) | Every page on the site | Settings → Code Injection → Site Header |
|
||||
| **Per-post** | Single post only | Post Settings → Code Injection → Post Header |
|
||||
| **Per-page** | Single page only | Page Settings → Code Injection → Post Header |
|
||||
| **ghost-cli** | Per-post via API | `ghost-cli --site <name> schema inject <slug> --file <path>` |
|
||||
|
||||
### Per-Page Schema via ghost-cli
|
||||
|
||||
The ghost-cli `schema inject` command handles the API call and stores the schema in the post's `codeinjection_head` field:
|
||||
|
||||
```bash
|
||||
# Validate and inject FAQPage schema
|
||||
ghost-cli --site example schema validate --json '{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Q?","acceptedAnswer":{"@type":"Answer","text":"A."}}]}'
|
||||
|
||||
ghost-cli --site example schema inject my-post --file /tmp/faq-schema.json
|
||||
```
|
||||
|
||||
### Injecting Multiple Schema Types with @graph
|
||||
|
||||
When a post benefits from multiple schema types (e.g., TechArticle + FAQPage), wrap them in a `@graph` array:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "TechArticle",
|
||||
"headline": "Post Title",
|
||||
"proficiencyLevel": "Advanced",
|
||||
"about": {"@type": "Thing", "name": "AI Agent Memory"}
|
||||
},
|
||||
{
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{"@type": "Question", "name": "Q1?", "acceptedAnswer": {"@type": "Answer", "text": "A1."}},
|
||||
{"@type": "Question", "name": "Q2?", "acceptedAnswer": {"@type": "Answer", "text": "A2."}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Schema Coverage by Site
|
||||
|
||||
| Site | Required Schema | Injection Method |
|
||||
|------|----------------|------------------|
|
||||
| **example.com** | Organization (site-wide), TechArticle (per-post), FAQPage (when applicable) | ghost-cli `schema inject` for per-post; Code Injection → Settings for site-wide |
|
||||
| **example.org** | Organization + areaServed (site-wide), Article (auto), FAQPage (FAQ content), LocalBusiness if applicable | Same pattern |
|
||||
| **example.net** | Organization (site-wide), Article (auto) | Same pattern |
|
||||
|
||||
### Validation
|
||||
|
||||
Every schema injection must be validated:
|
||||
|
||||
1. **Google Rich Results Test:** https://search.google.com/test/rich-results
|
||||
2. **Schema.org Validator:** https://validator.schema.org/
|
||||
3. **Manual check:** View page source → search for `application/ld+json`
|
||||
|
||||
## Completion Checklist
|
||||
|
||||
For every article publish:
|
||||
|
||||
- [ ] **Meta Title** set (50-60 chars, keyword front-loaded)
|
||||
- [ ] **Meta Description** set (150-160 chars, includes keyword + CTA)
|
||||
- [ ] **Custom Excerpt** set (1-2 sentence summary for cards)
|
||||
- [ ] **OG Image** set (article feature image or explicit OG image)
|
||||
- [ ] **OG Title** verified (at minimum, confirm it defaults acceptably)
|
||||
- [ ] **OG Description** verified (at minimum, confirm it defaults acceptably)
|
||||
- [ ] **Twitter card** type confirmed (summary_large_image)
|
||||
- [ ] **Canonical URL** confirmed (self-referencing unless syndicated)
|
||||
- [ ] **Schema injected** (TechArticle for example.com, FAQPage if applicable)
|
||||
- [ ] **Schema validated** (Google Rich Results Test passes)
|
||||
- [ ] **Feature image** has alt text and caption
|
||||
- [ ] **Slug** is optimized (30-45 chars, primary keyword, stable)
|
||||
|
||||
## Post-Publish Verification
|
||||
|
||||
```bash
|
||||
# 1. Check meta tags render
|
||||
curl -s https://<site>/<slug>/ | grep -E '<title|name="description"|property="og:|name="twitter:'
|
||||
|
||||
# 2. Check schema renders
|
||||
curl -s https://<site>/<slug>/ | grep 'application/ld+json'
|
||||
|
||||
# 3. Validate schema (requires the JSON block)
|
||||
# Pipe the extracted JSON-LD to the Rich Results Test API
|
||||
```
|
||||
@@ -0,0 +1,154 @@
|
||||
# On-Page SEO Reference
|
||||
|
||||
On-page optimization ensures each piece of content is structured and written to communicate relevance to search engines while serving the reader.
|
||||
|
||||
## Title Tags
|
||||
|
||||
The title tag is the single most important on-page SEO element. It appears in SERPs as the clickable headline.
|
||||
|
||||
### Best Practices
|
||||
- **Length:** 50-60 characters (Google typically displays the first 50-60 chars; titles longer than ~580px get truncated)
|
||||
- **Keyword placement:** Primary keyword near the beginning (front-loaded)
|
||||
- **Uniqueness:** Every page has a unique title tag — no duplicates
|
||||
- **Branding:** Include site/brand name at the end (separated by `—` or `|` in SERPs, but per the publication style rule, NO emdashes in prose — for title tags, use `|` as separator)
|
||||
- Example: `"SEO Audit for Ghost CMS Sites | Groktopus"`
|
||||
- Example: `"The Artifact Pyramid: Progressive Disclosure for Agent Outputs | Example Author"`
|
||||
- **Compelling:** Includes a value proposition or hook that earns the click
|
||||
- **No keyword stuffing:** Sounds natural, not like a list of keywords
|
||||
|
||||
### Platform-specific implementation notes — Patterns
|
||||
|
||||
**example.com (Hugo, PaperMod theme):**
|
||||
- Title set in frontmatter: `title: "..."`
|
||||
- Hugo auto-generates `<title>` from the title field
|
||||
- Verify: `title` in frontmatter is 50-60 chars
|
||||
- Site name appended automatically by PaperMod: `"Title | Example Author"`
|
||||
|
||||
**example.com (Ghost Pro):**
|
||||
- Meta title set in Ghost post settings → Meta Data → Custom Meta Title
|
||||
- Default: Post title (which may be too long — always set a custom meta title)
|
||||
- Ghost appends site name automatically in the `<title>` tag
|
||||
- Verify: custom meta title under 60 chars
|
||||
|
||||
**example.org / example.net (Ghost, self-hosted):**
|
||||
- Same as example.com — custom meta title in Ghost post settings
|
||||
|
||||
## Meta Descriptions
|
||||
|
||||
Not a direct ranking factor, but the second most important element for click-through rate from SERPs.
|
||||
|
||||
### Best Practices
|
||||
- **Length:** 150-160 characters (longer descriptions may be truncated)
|
||||
- **Includes primary keyword + secondary keyword naturally**
|
||||
- **Includes a call to action** ("Learn how...", "Discover why...", "Read the analysis")
|
||||
- **Unique per page** — no duplicate or auto-generated descriptions
|
||||
- **Matches search intent** — if someone searches for "progressive disclosure for agents," the description should signal that the page delivers on that query
|
||||
- **Contractions and natural language** — reads like a person wrote it
|
||||
|
||||
### Platform-specific implementation notes — Patterns
|
||||
|
||||
**example.com (Hugo, PaperMod):**
|
||||
- Hugo auto-generates meta description from page summary/content if not specified
|
||||
- Always set a `description:` field in frontmatter that's 150-160 chars
|
||||
- This is the meta description and also used in card previews
|
||||
|
||||
**example.com (Ghost Pro):**
|
||||
- Custom Meta Description in post settings → Meta Data
|
||||
- Ghost also uses this for Open Graph description
|
||||
- If not set, Ghost uses the post excerpt (which may be longer or shorter than ideal)
|
||||
|
||||
## Heading Structure
|
||||
|
||||
Headings communicate content hierarchy to search engines and provide scanability for readers.
|
||||
|
||||
### Hierarchy Rules
|
||||
- **H1:** Exactly one per page. Should match the title tag (or be a slightly more readable version). Contains the primary keyword.
|
||||
- **H2:** Major sections of the content. Each H2 should contain a related keyword or subtopic. Used as navigation anchors.
|
||||
- **H3-H6:** Subsections under H2s. Deeper hierarchy for complex content.
|
||||
- **No skipping levels:** Don't jump from H1 to H3. Hierarchically nested.
|
||||
|
||||
### Checklist
|
||||
- [ ] Exactly one H1 per page
|
||||
- [ ] H1 matches or closely relates to the title tag
|
||||
- [ ] H1 contains primary keyword
|
||||
- [ ] Headings form a logical outline of the page when read alone
|
||||
- [ ] No empty headings or headings used purely for styling
|
||||
- [ ] Keywords appear naturally in headings (not stuffed)
|
||||
- [ ] H2s and H3s are descriptive, not generic ("Introduction" is weak; "Why Progressive Disclosure Matters for AI Agents" is strong)
|
||||
|
||||
## Content Quality
|
||||
|
||||
### Keyword Usage
|
||||
- **Primary keyword appears in:** H1, first paragraph, at least one H2, URL slug
|
||||
- **Keyword density:** Natural usage — don't target specific percentages. If the keyword appears naturally 3-5 times in a 1500-word article, that's fine.
|
||||
- **LSI / related keywords:** Include semantically related terms that help establish topical relevance (e.g., for an article about "artifact pyramids," include terms like "progressive disclosure," "multi-agent pipelines," "agent collaboration")
|
||||
- **No keyword stuffing:** Don't repeat the same phrase unnaturally
|
||||
|
||||
### Content Length
|
||||
- **Blog posts:** 1500-2500 words is typical for long-form content. long-form articles often run longer because they're deep analytical pieces. Longer is fine if every word earns its place.
|
||||
- **Minimum to rank:** 300 words for very simple queries; 1000+ for competitive terms
|
||||
- **Quality over quantity:** A tight 800-word post that answers the query completely beats a padded 2000-word post that repeats itself
|
||||
|
||||
### Readability
|
||||
- Short paragraphs (2-4 sentences for web reading)
|
||||
- Bullet points and numbered lists for scannable information
|
||||
- Bold key terms for emphasis (sparingly)
|
||||
- Clear section breaks with descriptive headings
|
||||
|
||||
### Freshness
|
||||
- Update dates on evergreen content when significantly revised
|
||||
- Add "Last updated" or "Updated" notation for major content refreshes
|
||||
- Google favors freshness for certain query types (news, recent events, technology)
|
||||
|
||||
## Internal Linking
|
||||
|
||||
Internal links distribute page authority throughout the site and help crawlers discover content.
|
||||
|
||||
### Best Practices
|
||||
- **Link to related content:** Every post should link to 2-5 other posts/pages on the same site
|
||||
- **Descriptive anchor text:** Use the target topic's keyword as the link text (not "click here" or "read more")
|
||||
- **Link to cornerstone content:** Important pillar pages should receive more internal links
|
||||
- **Natural placement:** Links should serve the reader — if it genuinely helps to read more about X, link it
|
||||
- **Avoid:** Links in navigation that aren't needed, links to the same target with different anchor text, links on every instance of a term
|
||||
|
||||
### Platform-specific implementation notes — Patterns
|
||||
|
||||
**example.com:** Magnus uses [[wikilinks]] in draft which Hugo converts to hyperlinks. Check that wikilinks are rendering as live HTML links and pointing to existing pages.
|
||||
|
||||
**example.com (Ghost):** Manual internal links in the editor. Verify that linked posts exist and are published.
|
||||
|
||||
## Image Optimization
|
||||
|
||||
### Alt Text
|
||||
- **Purpose:** Accessibility for screen readers + context for search engines (Google Images)
|
||||
- **Every image** must have a descriptive alt attribute
|
||||
- **Descriptive:** "Close-up of a Portia labiata spider's principal eyes showing the characteristic three-lens system" — not "Portia spider" or "image001.jpg"
|
||||
- **Keyword-optimized:** Include relevant keywords naturally when they describe the image
|
||||
- **No keyword stuffing:** Alt text is first for accessibility, second for SEO
|
||||
- **Decorative images:** alt="" (empty alt) for purely decorative images so screen readers skip them
|
||||
|
||||
### File Names
|
||||
- Descriptive, hyphenated: `portia-spider-eyes-closeup.jpg` not `IMG_4732.jpg`
|
||||
- Include target keyword when appropriate
|
||||
- Use hyphens, not underscores
|
||||
|
||||
### File Size
|
||||
- Compress images before upload (target < 100KB for standard inline images)
|
||||
- Use next-gen formats: WebP (with JPEG fallback for older browsers)
|
||||
- Hugo: Use `.WebP` processing or serve via CDN that auto-converts
|
||||
- Ghost: Compress before uploading — Ghost does minimal image optimization
|
||||
|
||||
## URL Structure
|
||||
|
||||
### Best Practices
|
||||
- **Short, descriptive:** `/seo-audit-ghost-cms/` not `/post/12345/`
|
||||
- **Include primary keyword:** When natural
|
||||
- **Hyphens, not underscores:** Google treats hyphens as word separators
|
||||
- **Lowercase:** /seo-audit not /SEO-Audit
|
||||
- **Stop words:** Remove unnecessary "and", "the", "of", "for" where they don't add meaning
|
||||
- **Stable:** Once published, never change a URL (breaks all inbound links)
|
||||
|
||||
### Platform-specific implementation notes — Patterns
|
||||
- **example.com:** Hugo uses the post slug from frontmatter or filename. Verify slug is short and contains primary keyword.
|
||||
- **example.com:** Ghost auto-generates slug from title. Set a custom slug in post settings if the auto-generated one is too long or doesn't contain the keyword.
|
||||
- **Never change published slugs** without explicit approval from the site owner.
|
||||
@@ -0,0 +1,244 @@
|
||||
# Schema Markup / Structured Data Reference
|
||||
|
||||
Structured data helps search engines understand the content of a page and enables rich results in SERPs (FAQ snippets, HowTo steps, breadcrumbs, article previews).
|
||||
|
||||
## JSON-LD Format
|
||||
|
||||
Google's preferred format. Structured data is typically JSON-LD injected through the CMS, application templates, or a supported code-injection mechanism.
|
||||
|
||||
### Basic Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Title of the Article",
|
||||
"description": "150-160 char meta description",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Example Author"
|
||||
},
|
||||
"datePublished": "2026-05-01",
|
||||
"dateModified": "2026-05-15",
|
||||
"image": "https://example.com/image.jpg",
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Groktopus",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "https://www.example.com/favicon.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Schema Types for Platform-specific implementation notes
|
||||
|
||||
### TechArticle (example.com)
|
||||
Use for technical/analytical content about AI, enterprise technology, and engineering.
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"headline": "Article Title",
|
||||
"description": "Description",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Example Author"
|
||||
},
|
||||
"datePublished": "2026-05-01",
|
||||
"dateModified": "2026-05-15",
|
||||
"proficiencyLevel": "Advanced",
|
||||
"about": {
|
||||
"@type": "Thing",
|
||||
"name": "Topic area"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Article / BlogPosting (example.com)
|
||||
Use for personal blog and analytical long-form content.
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": "Title",
|
||||
"description": "Description",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Example Author"
|
||||
},
|
||||
"datePublished": "2026-05-01",
|
||||
"dateModified": "2026-05-15"
|
||||
}
|
||||
```
|
||||
|
||||
For articles authored by Jasper:
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": "Title",
|
||||
"description": "Description",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Jasper"
|
||||
},
|
||||
"datePublished": "2026-05-01",
|
||||
"dateModified": "2026-05-15"
|
||||
}
|
||||
```
|
||||
|
||||
### FAQPage (All Sites)
|
||||
Use when the article answers multiple distinct questions. Enables FAQ rich results in SERPs.
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Question 1?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Answer text here."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Question 2?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Answer text here."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Requirements for Google rich result eligibility:**
|
||||
- Minimum 2 questions
|
||||
- Questions must be visible text on the page (not hidden)
|
||||
- Each Question must match visible content
|
||||
- Answers must be clearly visible to the user (not just in schema)
|
||||
- Google may show up to 4 FAQ entries in the SERP
|
||||
|
||||
### HowTo (Tutorials, Technical Guides)
|
||||
Use for step-by-step guides and tutorials on any site.
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
"name": "How to Title",
|
||||
"description": "Description of the tutorial",
|
||||
"step": [
|
||||
{
|
||||
"@type": "HowToStep",
|
||||
"position": 1,
|
||||
"name": "Step 1",
|
||||
"text": "Description of step 1."
|
||||
},
|
||||
{
|
||||
"@type": "HowToStep",
|
||||
"position": 2,
|
||||
"name": "Step 2",
|
||||
"text": "Description of step 2."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### BreadcrumbList (Site Navigation)
|
||||
Use on all sites to enable breadcrumb rich results in SERPs.
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Home",
|
||||
"item": "https://www.example.com/"
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "Category",
|
||||
"item": "https://www.example.com/category/"
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 3,
|
||||
"name": "Article Title",
|
||||
"item": "https://www.example.com/article-slug/"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Organization (Site-level)
|
||||
Use on all sites for site-level schema (injected globally, not per-page).
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Site Name",
|
||||
"url": "https://www.example.com/",
|
||||
"logo": "https://www.example.com/favicon.png",
|
||||
"sameAs": [
|
||||
"https://twitter.com/username",
|
||||
"https://github.com/username"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Platform-Specific Implementation
|
||||
|
||||
### Ghost CMS (example.com, example.org, example.net)
|
||||
|
||||
**Per-page schema:**
|
||||
- Ghost injects basic JSON-LD automatically (Article type with headline, dates, author)
|
||||
- Custom schema (FAQPage, HowTo, TechArticle) goes in:
|
||||
- Post-level: Settings → Code Injection → Post Header (`<script type="application/ld+json">...</script>`)
|
||||
- Site-level: Settings → Code Injection → Site Header (BreadcrumbList, Organization)
|
||||
|
||||
**Verification:**
|
||||
- View source → search for `application/ld+json`
|
||||
- Test with Google Rich Results Test: https://search.google.com/test/rich-results
|
||||
- Test with Schema.org Validator: https://validator.schema.org/
|
||||
|
||||
**Ghost auto-generated schema limitations:**
|
||||
- Ghost only generates Article/BlogPosting schema by default
|
||||
- FAQPage, HowTo, TechArticle, BreadcrumbList, Product all require custom injection
|
||||
- Author info in Ghost's default schema may need enrichment (add author URL, sameAs)
|
||||
|
||||
### Hugo (example.com)
|
||||
|
||||
**Per-page schema:**
|
||||
- Add JSON-LD via Hugo template in `layouts/partials/head.html` or `layouts/_default/single.html`
|
||||
- Use Hugo's `.Params` to inject article-specific values
|
||||
- Conditional schema: `{{ if .Params.faq }}` for FAQPage, `{{ if .Params.howto }}` for HowTo
|
||||
|
||||
**Site-level schema:**
|
||||
- Organization and BreadcrumbList in the base template (`baseof.html`)
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [ ] JSON is valid (no trailing commas, properly closed braces)
|
||||
- [ ] Required fields present for each @type
|
||||
- [ ] URLs are absolute (including https://)
|
||||
- [ ] Dates are in ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ)
|
||||
- [ ] Author names match the byline
|
||||
- [ ] @context is set to "https://schema.org"
|
||||
- [ ] No conflicting or duplicate schema on the page
|
||||
- [ ] FAQPage content matches visible page content (no hidden answers)
|
||||
- [ ] Google Rich Results Test passes without errors
|
||||
- [ ] Schema content is visible to users where required (FAQPage, HowTo)
|
||||
@@ -0,0 +1,6 @@
|
||||
# Source index
|
||||
|
||||
- **Source repository:** https://github.com/magnus919/hermes-profiles
|
||||
- **Inspected commit:** `867a555`
|
||||
- **Imported source directory:** `seo-audit`
|
||||
- **Porting boundary:** Retained portable methodology, templates, scripts, and references. Removed or generalized Hermes profile, task-orchestration, memory, and rigid response-handoff assumptions.
|
||||
@@ -0,0 +1,99 @@
|
||||
# Technical SEO Reference
|
||||
|
||||
Technical SEO ensures search engines can find, crawl, interpret, and index your content. If the technical foundation is broken, nothing else matters.
|
||||
|
||||
## Crawlability & Indexability
|
||||
|
||||
### Robots.txt
|
||||
- **Purpose:** Directs crawlers which URLs to avoid
|
||||
- **Check:** Does the site have a robots.txt at `/robots.txt`?
|
||||
- **Check:** Are important pages accidentally disallowed? `Disallow: /` blocks ALL crawlers
|
||||
- **Check:** Is the sitemap referenced? `Sitemap: https://example.com/sitemap.xml`
|
||||
- **Best practice:** Allow CSS/JS files (modern crawlers need them for rendering)
|
||||
- **Hosted CMS sites:** Ghost CMS auto-generates robots.txt; verify after any config change
|
||||
|
||||
### XML Sitemaps
|
||||
- **Purpose:** Tells crawlers about all pages and their relative importance
|
||||
- **Check:** Does the sitemap exist and is it referenced in robots.txt?
|
||||
- **Check:** Are only canonical URLs included? (No pagination params, sort filters, etc.)
|
||||
- **Check:** Are noindex pages excluded from the sitemap?
|
||||
- **Check:** Lastmod dates are accurate (not all the same date)
|
||||
- **Ghost split sitemaps:** Ghost generates `sitemap-posts.xml`, `sitemap-pages.xml`, `sitemap-tags.xml`, `sitemap-authors.xml`. Verify each is present and valid.
|
||||
- **Hugo:** Verify sitemap.xml is generated with correct `changefreq` and `priority` settings
|
||||
|
||||
### Canonical URLs
|
||||
- **Purpose:** Tells search engines which URL is the authoritative version of a page
|
||||
- **Check:** Every page has a self-referencing canonical or points to the canonical version
|
||||
- **Check:** No conflicting canonicals (page A canonicals to B, B canonicals to C)
|
||||
- **Common issues:** HTTP/HTTPS duplication (canonical must use HTTPS if site is HTTPS), www/non-www duplication, trailing slash inconsistency
|
||||
- **Ghost:** Canonical is auto-generated from the post/page slug. Verify no slug changes break inbound canonical signals.
|
||||
|
||||
### Meta Robots / Noindex
|
||||
- **Purpose:** Prevents indexing of specific pages
|
||||
- **Check:** Pages that should be indexed don't have `<meta name="robots" content="noindex">`
|
||||
- **Check:** Thin pages (tag pages, author pages, pagination) have noindex if they shouldn't rank
|
||||
- **Check:** Login/admin pages have noindex
|
||||
|
||||
## Page Speed
|
||||
|
||||
### Core Web Vitals (Google's ranking signals)
|
||||
- **LCP (Largest Contentful Paint):** < 2.5s (good), 2.5-4.0s (needs improvement), > 4.0s (poor)
|
||||
- **FID (First Input Delay) / INP (Interaction to Next Paint):** < 100ms (good), 100-300ms (needs improvement), > 300ms (poor)
|
||||
- **CLS (Cumulative Layout Shift):** < 0.1 (good), 0.1-0.25 (needs improvement), > 0.25 (poor)
|
||||
|
||||
### Common Fixes by Platform
|
||||
|
||||
**Ghost CMS:**
|
||||
- Enable lazy loading for images (Ghost 5+ has built-in)
|
||||
- Use a CDN for image delivery (Ghost Pro includes; self-hosted needs Cloudflare or similar)
|
||||
- Limit the number of visible posts on home/tag pages (paginate aggressively)
|
||||
- Disable unused Ghost integrations and background tasks
|
||||
- Verify the theme isn't loading unused CSS/JS (many Ghost themes are bloated)
|
||||
|
||||
**Hugo (example.com):**
|
||||
- Hugo generates static HTML — inherently fast
|
||||
- Image processing: use Hugo's built-in image processing to serve appropriately sized images (`.Resize`, `.Fill`, `.Fit`)
|
||||
- Minify HTML output: `minify: true` in config
|
||||
- Avoid excessive JavaScript (Hugo sites shouldn't need much JS)
|
||||
- Verify CSS is not render-blocking (inline critical CSS if needed)
|
||||
|
||||
### Tools for Measurement
|
||||
- Google PageSpeed Insights (lab + field data)
|
||||
- Lighthouse (Chrome DevTools)
|
||||
- Web Vitals library (RUM data)
|
||||
- GTmetrix / Pingdom (third-party)
|
||||
|
||||
## Mobile-Friendliness
|
||||
|
||||
- **Check:** Responsive design — does the site render correctly at all viewport widths?
|
||||
- **Check:** Viewport meta tag present: `<meta name="viewport" content="width=device-width, initial-scale=1">`
|
||||
- **Check:** Font sizes are readable on mobile (min 16px body text recommended)
|
||||
- **Check:** Tap targets are adequately sized (min 48x48px recommended)
|
||||
- **Check:** Content not hidden behind unplayable media or unsupported formats
|
||||
- **Test:** Google's Mobile-Friendly Test
|
||||
|
||||
## HTTPS & Security
|
||||
|
||||
- **Check:** Valid SSL certificate (not expired, not self-signed)
|
||||
- **Check:** All resources load over HTTPS (no mixed content warnings)
|
||||
- **Check:** HSTS header present for repeat visitors (Strict-Transport-Security)
|
||||
- **Check:** Redirects HTTP → HTTPS (301 permanent redirect)
|
||||
- **Check:** No security warnings in browser (mixed content, invalid cert)
|
||||
|
||||
## International SEO (If Applicable)
|
||||
|
||||
- **hreflang tags:** Correctly implemented for multi-language/multi-region sites
|
||||
- **Check:** Self-referencing hreflang (each page includes its own language tag as well)
|
||||
- **Check:** No conflicting signals (hreflang says X, redirect says Y)
|
||||
|
||||
## Ghost-Specific Technical SEO
|
||||
|
||||
| Check | Where to look | Action |
|
||||
|-------|---------------|--------|
|
||||
| Canonical URLs | Post settings → canonical URL | Verify self-referencing or correct canonical |
|
||||
| Meta robots | Code injection → per-page | No thin pages indexed |
|
||||
| Sitemap | `/sitemap.xml` | Verify split sitemaps present |
|
||||
| Robots.txt | `/robots.txt` | Verify sitemaps referenced, no accidental disallows |
|
||||
| Structured data | Source HTML → JSON-LD | Verify Ghost's built-in JSON-LD is correct + any custom |
|
||||
| AMP | Ghost settings | Verify AMP is enabled/disabled intentionally (Ghost defaults to disabled in v5+) |
|
||||
| Open Graph / Twitter Cards | Post social settings | Verify Facebook and Twitter card previews |
|
||||
Reference in New Issue
Block a user