From 326ee3e0d2f8a3eab901ac8a3730810dd30ef6e2 Mon Sep 17 00:00:00 2001 From: tommylower Date: Fri, 24 Jul 2026 16:36:04 -0400 Subject: [PATCH 1/2] Add SEO and AEO implementation skill --- README.md | 1 + engineering/AGENTS.md | 1 + engineering/seo-aeo-best-practices/SKILL.md | 37 ++++ .../references/aeo-considerations.md | 159 +++++++++++++++ .../references/eeat-principles.md | 127 ++++++++++++ .../references/structured-data.md | 183 +++++++++++++++++ .../references/technical-seo.md | 188 ++++++++++++++++++ 7 files changed, 696 insertions(+) create mode 100644 engineering/seo-aeo-best-practices/SKILL.md create mode 100644 engineering/seo-aeo-best-practices/references/aeo-considerations.md create mode 100644 engineering/seo-aeo-best-practices/references/eeat-principles.md create mode 100644 engineering/seo-aeo-best-practices/references/structured-data.md create mode 100644 engineering/seo-aeo-best-practices/references/technical-seo.md diff --git a/README.md b/README.md index 28c18ca..020afc7 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Every category has an `AGENTS.md` index. Start there. The library rule: you shou - `tdd`, `diagnose`, `prototype` — building discipline - `to-prd`, `to-issues`, `triage` — planning and tickets - `handoff` — close out a token-heavy session with pre-clear checks and a short restart prompt +- `seo-aeo-best-practices` — technical SEO, structured data, EEAT, and AI-answer implementation guidance - `write-a-skill`, `writing-great-skills` — author and refine skills with proper structure, attribution, and predictable behavior - `deadcode` — find and remove unused code and dependencies diff --git a/engineering/AGENTS.md b/engineering/AGENTS.md index 6805b97..a595fe2 100644 --- a/engineering/AGENTS.md +++ b/engineering/AGENTS.md @@ -27,6 +27,7 @@ they stack. grill-with-docs maintains the `CONTEXT.md` glossary and ADRs that im - **tdd** — red-green-refactor loop, one vertical slice at a time. references on deep modules, interface design, mocking, refactoring, what makes good tests. - **prototype** — throwaway prototype to flesh out a design: terminal app for state/logic questions, or multiple UI variations on one route. - **diagnose** — disciplined debugging loop: reproduce → minimise → hypothesise → instrument → fix → regression-test. +- **seo-aeo-best-practices** — implementation guidance for technical SEO, metadata, structured data, internationalization, EEAT, and AI-answer readiness. ## planning and tickets diff --git a/engineering/seo-aeo-best-practices/SKILL.md b/engineering/seo-aeo-best-practices/SKILL.md new file mode 100644 index 0000000..ade2bb5 --- /dev/null +++ b/engineering/seo-aeo-best-practices/SKILL.md @@ -0,0 +1,37 @@ +--- +name: seo-aeo-best-practices +description: SEO and AEO best practices for metadata, Open Graph, sitemaps, robots.txt, hreflang, JSON-LD structured data, EEAT, and content optimized for search engines and AI answer surfaces. Use this skill when implementing page SEO, technical SEO, schema markup, international SEO, AI-overview readiness, or improving content for Google, ChatGPT, Perplexity, and similar assistants. +--- + +# SEO & AEO Best Practices + +Principles for optimizing content for both traditional search engines (SEO) and AI-powered answer engines (AEO). Includes Google's EEAT guidelines and structured data implementation. + +## When to Apply + +Reference these guidelines when: +- Implementing metadata and Open Graph tags +- Creating sitemaps and robots.txt +- Adding JSON-LD structured data +- Optimizing content for featured snippets +- Preparing content for AI assistants (ChatGPT, Perplexity, etc.) +- Evaluating content quality using EEAT principles + +## Core Concepts + +### SEO (Search Engine Optimization) +Optimizing content to rank well in traditional search results (Google, Bing). + +### AEO (Answer Engine Optimization) +Optimizing content to be selected as authoritative answers by AI systems. + +### EEAT (Experience, Expertise, Authoritativeness, Trustworthiness) +Google's framework for evaluating content quality. + +## References + +Start with the one reference that matches the task, such as technical SEO, structured data, EEAT, or AI-answer readiness. See `references/` for detailed guidance: +- `references/eeat-principles.md` — EEAT implementation and author schema +- `references/structured-data.md` — JSON-LD patterns (Article, FAQ, Breadcrumb, Product) +- `references/technical-seo.md` — Technical SEO checklist (metadata, sitemaps, hreflang, robots.txt) +- `references/aeo-considerations.md` — AI/AEO considerations (AI Overviews, crawler management) diff --git a/engineering/seo-aeo-best-practices/references/aeo-considerations.md b/engineering/seo-aeo-best-practices/references/aeo-considerations.md new file mode 100644 index 0000000..227d79e --- /dev/null +++ b/engineering/seo-aeo-best-practices/references/aeo-considerations.md @@ -0,0 +1,159 @@ +# AI/AEO Considerations + +Answer Engine Optimization (AEO) prepares content to be selected as authoritative answers by AI systems like ChatGPT, Perplexity, Google AI Overviews, and Bing Copilot. + +## How AI Selects Answers + +AI systems evaluate content based on: + +1. **Clarity:** Is the answer direct and easy to extract? +2. **Authority:** Is the source trustworthy? +3. **Comprehensiveness:** Does it fully address the question? +4. **Recency:** Is the information up to date? +5. **Structure:** Can the AI parse and understand it? + +## Content Structure for AI + +### Direct Answers First +Lead with the answer, then explain. + +**Bad:** +> The history of JavaScript dates back to 1995 when Brendan Eich... [500 words later] ...JavaScript runs in the browser. + +**Good:** +> JavaScript is a programming language that runs in web browsers. It was created in 1995 by Brendan Eich... + +### Clear Headings +Use descriptive H2/H3 headings that match user questions. + +**Bad:** "Overview" → "Details" → "More Information" +**Good:** "What is X?" → "How does X work?" → "When should you use X?" + +### Lists and Tables +AI extracts structured information more easily than prose. + +```markdown +## Benefits of Structured Content + +- **Reusability:** Use content across channels +- **Flexibility:** Change presentation without changing content +- **Scalability:** Manage large content volumes +``` + +### FAQ Format +Question-answer pairs are ideal for AI extraction. + +```typescript +// Schema for AI-friendly FAQs +defineType({ + name: 'faq', + type: 'document', + fields: [ + defineField({ name: 'question', type: 'string' }), + defineField({ name: 'answer', type: 'text' }), + defineField({ name: 'category', type: 'reference', to: [{ type: 'faqCategory' }] }), + ] +}) +``` + +## Technical Implementation + +### Structured Data (Critical) +JSON-LD helps AI understand content type and relationships. + +```typescript +// FAQ structured data +const faqSchema = { + "@context": "https://schema.org", + "@type": "FAQPage", + mainEntity: faqs.map(faq => ({ + "@type": "Question", + name: faq.question, + acceptedAnswer: { + "@type": "Answer", + text: faq.answer + } + })) +} +``` + +### Canonical Content +Ensure AI finds your authoritative version, not copies. + +- Set canonical URLs +- Avoid duplicate content across pages +- Use `rel="canonical"` for syndicated content + +### Freshness Signals +AI systems prefer current information. + +- Display publish and update dates prominently +- Update content regularly with substantive changes (superficial updates like changing dates without meaningful edits can be counterproductive) +- Use `dateModified` in structured data + +## Content Quality Signals + +### Author Credentials +AI systems increasingly check author authority. + +- Display author name and credentials +- Link to author profiles +- Include author structured data + +### Citations and Sources +Linking to authoritative sources increases trust. + +- Cite primary sources +- Link to studies, documentation, official sources +- Avoid circular citations (sites citing each other) + +### Comprehensive Coverage +AI prefers content that fully answers questions. + +- Cover related questions users might have +- Include definitions for technical terms +- Address common misconceptions + +## Google AI Overviews + +Google's AI Overviews (formerly SGE) now appear in many search results. To optimize: + +- **Be the cited source:** AI Overviews cite specific pages. Concise, authoritative answers increase citation likelihood. +- **Structure for extraction:** Use clear headings, direct answers, and lists that AI can easily parse. +- **Cover follow-up questions:** AI Overviews often address related queries. Anticipate and answer them on the same page or link to dedicated pages. +- **Monitor in Search Console:** Google Search Console provides data on AI Overview impressions and clicks. + +## AI Crawler Management + +Make conscious decisions about which AI systems can crawl your content: + +- **robots.txt directives:** Use `User-agent: GPTBot`, `ClaudeBot`, `PerplexityBot`, `Google-Extended` to control access. +- **Allowing crawlers** increases chances of being cited as a source in AI responses. +- **Blocking crawlers** prevents content from being used in AI training (but may reduce AI citations). +- Review your policy regularly — this is one of the most actively evolving areas of SEO. + +## Measuring AEO Success + +### Monitor AI Mentions +Track when AI assistants cite your content: +- Use Google Search Console's AI Overview data for impression and click tracking +- Monitor referral traffic from AI platforms (Perplexity, ChatGPT, Bing Copilot) +- Search for your brand + "according to" in AI assistants +- Consider third-party AEO tracking tools for comprehensive monitoring + +### Track Zero-Click Queries +If AI answers questions directly, traditional rankings matter less. + +### Featured Snippet Capture +Featured snippets often become AI answers. Track which you own. + +## AEO vs SEO Balance + +AEO and SEO largely align—quality content serves both. Key differences: + +| Aspect | SEO Focus | AEO Focus | +|--------|-----------|-----------| +| Goal | Rank on page 1 | Be THE answer | +| Format | Varies | Direct, structured | +| Length | Often longer | Concise + comprehensive | +| Links | Link building | Source citations | diff --git a/engineering/seo-aeo-best-practices/references/eeat-principles.md b/engineering/seo-aeo-best-practices/references/eeat-principles.md new file mode 100644 index 0000000..3db0523 --- /dev/null +++ b/engineering/seo-aeo-best-practices/references/eeat-principles.md @@ -0,0 +1,127 @@ +# EEAT Principles + +Google's EEAT framework (Experience, Expertise, Authoritativeness, Trustworthiness) guides how content quality is evaluated. This applies to both SEO rankings and AI answer selection. + +## The Four Pillars + +### Experience +First-hand or life experience with the topic. + +**Signals:** +- Personal anecdotes and case studies +- "I tested this" content +- Real-world results and screenshots +- User-generated reviews + +**Implementation:** +- Include author bios with relevant experience +- Add "About the Author" sections +- Feature customer testimonials +- Show real examples, not just theory + +### Expertise +Knowledge and skill in the subject area. + +**Signals:** +- Credentials and qualifications +- Depth of content coverage +- Technical accuracy +- Citations to authoritative sources + +**Implementation:** +- Display author credentials +- Link to primary sources +- Cover topics comprehensively +- Keep content technically accurate and updated + +### Authoritativeness +Recognition as a go-to source in the field. + +**Signals:** +- Backlinks from respected sites +- Mentions in industry publications +- Social proof and follower counts +- Brand recognition + +**Implementation:** +- Build thought leadership content +- Contribute to industry publications +- Maintain consistent publishing +- Develop recognizable brand voice + +### Trustworthiness +Accuracy, transparency, and legitimacy. + +**Signals:** +- Clear authorship and contact info +- Accurate, fact-checked content +- Secure website (HTTPS) +- Privacy policy and terms + +**Implementation:** +- Display clear author attribution +- Include publication and update dates +- Provide contact information +- Use HTTPS and maintain security + +## Sanity Implementation + +```typescript +// Author schema with EEAT signals +defineType({ + name: 'author', + type: 'document', + fields: [ + defineField({ name: 'name', type: 'string' }), + defineField({ name: 'role', type: 'string' }), + defineField({ name: 'bio', type: 'text' }), + defineField({ name: 'credentials', type: 'array', of: [{ type: 'string' }] }), + defineField({ name: 'image', type: 'image' }), + // sameAs: used for schema.org Person structured data output + defineField({ name: 'sameAs', type: 'array', of: [{ type: 'url' }], + description: 'Canonical profile URLs (LinkedIn, Twitter, etc.) for schema.org Person' + }), + // socialLinks: used for display purposes (platform icons, labels) + defineField({ + name: 'socialLinks', + type: 'array', + of: [{ type: 'object', fields: [ + defineField({ name: 'platform', type: 'string' }), + defineField({ name: 'url', type: 'url' }) + ]}], + description: 'Social links for display in the UI. Use sameAs for structured data output.' + }), + ] +}) + +// Content with EEAT metadata +defineType({ + name: 'post', + fields: [ + defineField({ name: 'author', type: 'reference', to: [{ type: 'author' }] }), + defineField({ name: 'publishedAt', type: 'datetime' }), + defineField({ name: 'updatedAt', type: 'datetime' }), + defineField({ + name: 'reviewedBy', + type: 'reference', + to: [{ type: 'author' }], + description: 'Expert reviewer for fact-checking' + }), + defineField({ + name: 'sources', + type: 'array', + of: [{ type: 'url' }], + description: 'Citations and references' + }), + ] +}) +``` + +## YMYL Considerations + +"Your Money or Your Life" topics (health, finance, legal, safety) require extra EEAT rigor: + +- Medical content reviewed by healthcare professionals +- Financial advice from certified experts +- Legal content reviewed by attorneys +- Clear disclaimers where appropriate diff --git a/engineering/seo-aeo-best-practices/references/structured-data.md b/engineering/seo-aeo-best-practices/references/structured-data.md new file mode 100644 index 0000000..84292dc --- /dev/null +++ b/engineering/seo-aeo-best-practices/references/structured-data.md @@ -0,0 +1,183 @@ +# Structured Data (JSON-LD) + +Structured data helps search engines and AI understand your content. JSON-LD is the recommended format. + +## Why Structured Data Matters + +- **Rich snippets:** Enhanced search result appearance +- **Knowledge panels:** Featured information boxes +- **AI training:** Better content understanding +- **Voice search:** Answer selection for voice queries + +## Common Schema Types + +### Article / Blog Post + +```typescript +import { Article, WithContext } from 'schema-dts' + +const articleSchema: WithContext
= { + "@context": "https://schema.org", + "@type": "Article", + headline: post.title, + description: post.excerpt, + image: post.image?.url, + datePublished: post.publishedAt, + dateModified: post.updatedAt, + author: { + "@type": "Person", + name: post.author.name, + url: post.author.url + }, + publisher: { + "@type": "Organization", + name: "Your Company", + logo: { + "@type": "ImageObject", + url: "https://example.com/logo.png" + } + } +} +``` + +### FAQ Page + +```typescript +import { FAQPage, WithContext } from 'schema-dts' + +const faqSchema: WithContext = { + "@context": "https://schema.org", + "@type": "FAQPage", + mainEntity: faqs.map(faq => ({ + "@type": "Question", + name: faq.question, + acceptedAnswer: { + "@type": "Answer", + text: faq.answer // Plain text, use pt::text() in GROQ + } + })) +} +``` + +### Organization + +```typescript +import { Organization, WithContext } from 'schema-dts' + +const orgSchema: WithContext = { + "@context": "https://schema.org", + "@type": "Organization", + name: "Your Company", + url: "https://example.com", + logo: "https://example.com/logo.png", + sameAs: [ + "https://twitter.com/company", + "https://linkedin.com/company/company" + ], + contactPoint: { + "@type": "ContactPoint", + telephone: "+1-555-555-5555", + contactType: "customer service" + } +} +``` + +### Product + +```typescript +import { Product, WithContext } from 'schema-dts' + +const productSchema: WithContext = { + "@context": "https://schema.org", + "@type": "Product", + name: product.name, + description: product.description, + image: product.images, + offers: { + "@type": "Offer", + price: product.price, + priceCurrency: "USD", + availability: "https://schema.org/InStock" + }, + aggregateRating: product.rating ? { + "@type": "AggregateRating", + ratingValue: product.rating.average, + reviewCount: product.rating.count + } : undefined +} +``` + +### Breadcrumb + +```typescript +import { BreadcrumbList, WithContext } from 'schema-dts' + +const breadcrumbSchema: WithContext = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: breadcrumbs.map((crumb, index) => ({ + "@type": "ListItem", + position: index + 1, // schema.org positions are 1-based + name: crumb.title, + item: `https://example.com${crumb.path}` + })) +} +``` + +## Combining Multiple Schemas (@graph) + +Real-world pages often need multiple schema types. Use `@graph` to combine them. The `@context` is defined once at the top level — omit it from individual schema generators when used inside `@graph`: + +```typescript +const pageSchema = { + "@context": "https://schema.org", + "@graph": [ + generateArticleSchema(post), // No @context needed here + generateBreadcrumbSchema(breadcrumbs), + generateOrganizationSchema(), + ] +} +``` + +## Implementation in Next.js + +```typescript +// Component to render JSON-LD +// Ensure data comes from trusted sources (your CMS). +// If data could contain user-generated content, strip HTML tags +// and escape special characters before passing to JSON.stringify. +function JsonLd({ data }: { data: WithContext }) { + return ( +