The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add SEO/AEO best practices skill from tigris-blog (#1161)

Copies the seo-aeo-best-practices skill including EEAT principles,
structured data patterns, technical SEO checklist, and AEO considerations.

https://claude.ai/code/session_01H2sEDhsTTK6nJix9ByNCoT

Co-authored-by: Claude <noreply@anthropic.com>

authored by

Xe Iaso
Claude
and committed by
GitHub
d62c0e73 ae2749bf

+669
+52
.agents/skills/seo-aeo-best-practices/SKILL.md
··· 1 + --- 2 + name: seo-aeo-best-practices 3 + description: 4 + SEO and AEO (Answer Engine Optimization) best practices including EEAT 5 + principles, structured data, and technical SEO. Use when implementing 6 + metadata, sitemaps, structured data, or optimizing content for search engines 7 + and AI assistants. 8 + license: MIT 9 + metadata: 10 + author: sanity 11 + version: "1.0.0" 12 + --- 13 + 14 + # SEO & AEO Best Practices 15 + 16 + Principles for optimizing content for both traditional search engines (SEO) and 17 + AI-powered answer engines (AEO). Includes Google's EEAT guidelines and 18 + structured data implementation. 19 + 20 + ## When to Apply 21 + 22 + Reference these guidelines when: 23 + 24 + - Implementing metadata and Open Graph tags 25 + - Creating sitemaps and robots.txt 26 + - Adding JSON-LD structured data 27 + - Optimizing content for featured snippets 28 + - Preparing content for AI assistants (ChatGPT, Perplexity, etc.) 29 + - Evaluating content quality using EEAT principles 30 + 31 + ## Core Concepts 32 + 33 + ### SEO (Search Engine Optimization) 34 + 35 + Optimizing content to rank well in traditional search results (Google, Bing). 36 + 37 + ### AEO (Answer Engine Optimization) 38 + 39 + Optimizing content to be selected as authoritative answers by AI systems. 40 + 41 + ### EEAT (Experience, Expertise, Authoritativeness, Trustworthiness) 42 + 43 + Google's framework for evaluating content quality. 44 + 45 + ## Resources 46 + 47 + See `resources/` for detailed guidance: 48 + 49 + - EEAT implementation 50 + - Structured data patterns 51 + - Technical SEO checklist 52 + - AI/AEO considerations
+164
.agents/skills/seo-aeo-best-practices/resources/aeo-considerations.md
··· 1 + # AI/AEO Considerations 2 + 3 + Answer Engine Optimization (AEO) prepares content to be selected as 4 + authoritative answers by AI systems like ChatGPT, Perplexity, Google AI 5 + Overviews, and Bing Copilot. 6 + 7 + ## How AI Selects Answers 8 + 9 + AI systems evaluate content based on: 10 + 11 + 1. **Clarity:** Is the answer direct and easy to extract? 12 + 2. **Authority:** Is the source trustworthy? 13 + 3. **Comprehensiveness:** Does it fully address the question? 14 + 4. **Recency:** Is the information up to date? 15 + 5. **Structure:** Can the AI parse and understand it? 16 + 17 + ## Content Structure for AI 18 + 19 + ### Direct Answers First 20 + 21 + Lead with the answer, then explain. 22 + 23 + **Bad:** 24 + 25 + > The history of JavaScript dates back to 1995 when Brendan Eich... [500 words > 26 + > > later] ...JavaScript runs in the browser. 27 + 28 + **Good:** 29 + 30 + > JavaScript is a programming language that runs in web browsers. It was created 31 + > in 1995 by Brendan Eich... 32 + 33 + ### Clear Headings 34 + 35 + Use descriptive H2/H3 headings that match user questions. 36 + 37 + **Bad:** "Overview" → "Details" → "More Information" **Good:** "What is X?" → 38 + "How does X work?" → "When should you use X?" 39 + 40 + ### Lists and Tables 41 + 42 + AI extracts structured information more easily than prose. 43 + 44 + ```markdown 45 + ## Benefits of Structured Content 46 + 47 + - **Reusability:** Use content across channels 48 + - **Flexibility:** Change presentation without changing content 49 + - **Scalability:** Manage large content volumes 50 + ``` 51 + 52 + ### FAQ Format 53 + 54 + Question-answer pairs are ideal for AI extraction. 55 + 56 + ```typescript 57 + // Schema for AI-friendly FAQs 58 + defineType({ 59 + name: "faq", 60 + type: "document", 61 + fields: [ 62 + defineField({ name: "question", type: "string" }), 63 + defineField({ name: "answer", type: "text" }), 64 + defineField({ 65 + name: "category", 66 + type: "reference", 67 + to: [{ type: "faqCategory" }], 68 + }), 69 + ], 70 + }); 71 + ``` 72 + 73 + ## Technical Implementation 74 + 75 + ### Structured Data (Critical) 76 + 77 + JSON-LD helps AI understand content type and relationships. 78 + 79 + ```typescript 80 + // FAQ structured data 81 + const faqSchema = { 82 + "@context": "https://schema.org", 83 + "@type": "FAQPage", 84 + mainEntity: faqs.map((faq) => ({ 85 + "@type": "Question", 86 + name: faq.question, 87 + acceptedAnswer: { 88 + "@type": "Answer", 89 + text: faq.answer, 90 + }, 91 + })), 92 + }; 93 + ``` 94 + 95 + ### Canonical Content 96 + 97 + Ensure AI finds your authoritative version, not copies. 98 + 99 + - Set canonical URLs 100 + - Avoid duplicate content across pages 101 + - Use `rel="canonical"` for syndicated content 102 + 103 + ### Freshness Signals 104 + 105 + AI systems prefer current information. 106 + 107 + - Display publish and update dates prominently 108 + - Update content regularly (even small updates signal freshness) 109 + - Use `dateModified` in structured data 110 + 111 + ## Content Quality Signals 112 + 113 + ### Author Credentials 114 + 115 + AI systems increasingly check author authority. 116 + 117 + - Display author name and credentials 118 + - Link to author profiles 119 + - Include author structured data 120 + 121 + ### Citations and Sources 122 + 123 + Linking to authoritative sources increases trust. 124 + 125 + - Cite primary sources 126 + - Link to studies, documentation, official sources 127 + - Avoid circular citations (sites citing each other) 128 + 129 + ### Comprehensive Coverage 130 + 131 + AI prefers content that fully answers questions. 132 + 133 + - Cover related questions users might have 134 + - Include definitions for technical terms 135 + - Address common misconceptions 136 + 137 + ## Measuring AEO Success 138 + 139 + ### Monitor AI Mentions 140 + 141 + Track when AI assistants cite your content: 142 + 143 + - Search for your brand + "according to" 144 + - Monitor traffic from AI platforms 145 + - Check Perplexity, Bing Copilot responses 146 + 147 + ### Track Zero-Click Queries 148 + 149 + If AI answers questions directly, traditional rankings matter less. 150 + 151 + ### Featured Snippet Capture 152 + 153 + Featured snippets often become AI answers. Track which you own. 154 + 155 + ## AEO vs SEO Balance 156 + 157 + AEO and SEO largely align—quality content serves both. Key differences: 158 + 159 + | Aspect | SEO Focus | AEO Focus | 160 + | ------ | -------------- | ----------------------- | 161 + | Goal | Rank on page 1 | Be THE answer | 162 + | Format | Varies | Direct, structured | 163 + | Length | Often longer | Concise + comprehensive | 164 + | Links | Link building | Source citations |
+149
.agents/skills/seo-aeo-best-practices/resources/eeat-principles.md
··· 1 + # EEAT Principles 2 + 3 + Google's EEAT framework (Experience, Expertise, Authoritativeness, 4 + Trustworthiness) guides how content quality is evaluated. This applies to both 5 + SEO rankings and AI answer selection. 6 + 7 + ## The Four Pillars 8 + 9 + ### Experience 10 + 11 + First-hand or life experience with the topic. 12 + 13 + **Signals:** 14 + 15 + - Personal anecdotes and case studies 16 + - "I tested this" content 17 + - Real-world results and screenshots 18 + - User-generated reviews 19 + 20 + **Implementation:** 21 + 22 + - Include author bios with relevant experience 23 + - Add "About the Author" sections 24 + - Feature customer testimonials 25 + - Show real examples, not just theory 26 + 27 + ### Expertise 28 + 29 + Knowledge and skill in the subject area. 30 + 31 + **Signals:** 32 + 33 + - Credentials and qualifications 34 + - Depth of content coverage 35 + - Technical accuracy 36 + - Citations to authoritative sources 37 + 38 + **Implementation:** 39 + 40 + - Display author credentials 41 + - Link to primary sources 42 + - Cover topics comprehensively 43 + - Keep content technically accurate and updated 44 + 45 + ### Authoritativeness 46 + 47 + Recognition as a go-to source in the field. 48 + 49 + **Signals:** 50 + 51 + - Backlinks from respected sites 52 + - Mentions in industry publications 53 + - Social proof and follower counts 54 + - Brand recognition 55 + 56 + **Implementation:** 57 + 58 + - Build thought leadership content 59 + - Contribute to industry publications 60 + - Maintain consistent publishing 61 + - Develop recognizable brand voice 62 + 63 + ### Trustworthiness 64 + 65 + Accuracy, transparency, and legitimacy. 66 + 67 + **Signals:** 68 + 69 + - Clear authorship and contact info 70 + - Accurate, fact-checked content 71 + - Secure website (HTTPS) 72 + - Privacy policy and terms 73 + 74 + **Implementation:** 75 + 76 + - Display clear author attribution 77 + - Include publication and update dates 78 + - Provide contact information 79 + - Use HTTPS and maintain security 80 + 81 + ## Sanity Implementation 82 + 83 + ```typescript 84 + // Author schema with EEAT signals 85 + defineType({ 86 + name: "author", 87 + type: "document", 88 + fields: [ 89 + defineField({ name: "name", type: "string" }), 90 + defineField({ name: "role", type: "string" }), 91 + defineField({ name: "bio", type: "text" }), 92 + defineField({ 93 + name: "credentials", 94 + type: "array", 95 + of: [{ type: "string" }], 96 + }), 97 + defineField({ name: "image", type: "image" }), 98 + defineField({ 99 + name: "socialLinks", 100 + type: "array", 101 + of: [ 102 + { 103 + type: "object", 104 + fields: [ 105 + defineField({ name: "platform", type: "string" }), 106 + defineField({ name: "url", type: "url" }), 107 + ], 108 + }, 109 + ], 110 + }), 111 + ], 112 + }); 113 + 114 + // Content with EEAT metadata 115 + defineType({ 116 + name: "post", 117 + fields: [ 118 + defineField({ 119 + name: "author", 120 + type: "reference", 121 + to: [{ type: "author" }], 122 + }), 123 + defineField({ name: "publishedAt", type: "datetime" }), 124 + defineField({ name: "updatedAt", type: "datetime" }), 125 + defineField({ 126 + name: "reviewedBy", 127 + type: "reference", 128 + to: [{ type: "author" }], 129 + description: "Expert reviewer for fact-checking", 130 + }), 131 + defineField({ 132 + name: "sources", 133 + type: "array", 134 + of: [{ type: "url" }], 135 + description: "Citations and references", 136 + }), 137 + ], 138 + }); 139 + ``` 140 + 141 + ## YMYL Considerations 142 + 143 + "Your Money or Your Life" topics (health, finance, legal, safety) require extra 144 + EEAT rigor: 145 + 146 + - Medical content reviewed by healthcare professionals 147 + - Financial advice from certified experts 148 + - Legal content reviewed by attorneys 149 + - Clear disclaimers where appropriate
+151
.agents/skills/seo-aeo-best-practices/resources/structured-data.md
··· 1 + # Structured Data (JSON-LD) 2 + 3 + Structured data helps search engines and AI understand your content. JSON-LD is 4 + the recommended format. 5 + 6 + ## Why Structured Data Matters 7 + 8 + - **Rich snippets:** Enhanced search result appearance 9 + - **Knowledge panels:** Featured information boxes 10 + - **AI training:** Better content understanding 11 + - **Voice search:** Answer selection for voice queries 12 + 13 + ## Common Schema Types 14 + 15 + ### Article / Blog Post 16 + 17 + ```typescript 18 + import { Article, WithContext } from "schema-dts"; 19 + 20 + const articleSchema: WithContext<Article> = { 21 + "@context": "https://schema.org", 22 + "@type": "Article", 23 + headline: post.title, 24 + description: post.excerpt, 25 + image: post.image?.url, 26 + datePublished: post.publishedAt, 27 + dateModified: post.updatedAt, 28 + author: { 29 + "@type": "Person", 30 + name: post.author.name, 31 + url: post.author.url, 32 + }, 33 + publisher: { 34 + "@type": "Organization", 35 + name: "Your Company", 36 + logo: { 37 + "@type": "ImageObject", 38 + url: "https://example.com/logo.png", 39 + }, 40 + }, 41 + }; 42 + ``` 43 + 44 + ### FAQ Page 45 + 46 + ```typescript 47 + import { FAQPage, WithContext } from "schema-dts"; 48 + 49 + const faqSchema: WithContext<FAQPage> = { 50 + "@context": "https://schema.org", 51 + "@type": "FAQPage", 52 + mainEntity: faqs.map((faq) => ({ 53 + "@type": "Question", 54 + name: faq.question, 55 + acceptedAnswer: { 56 + "@type": "Answer", 57 + text: faq.answer, // Plain text, use pt::text() in GROQ 58 + }, 59 + })), 60 + }; 61 + ``` 62 + 63 + ### Organization 64 + 65 + ```typescript 66 + import { Organization, WithContext } from "schema-dts"; 67 + 68 + const orgSchema: WithContext<Organization> = { 69 + "@context": "https://schema.org", 70 + "@type": "Organization", 71 + name: "Your Company", 72 + url: "https://example.com", 73 + logo: "https://example.com/logo.png", 74 + sameAs: [ 75 + "https://twitter.com/company", 76 + "https://linkedin.com/company/company", 77 + ], 78 + contactPoint: { 79 + "@type": "ContactPoint", 80 + telephone: "+1-555-555-5555", 81 + contactType: "customer service", 82 + }, 83 + }; 84 + ``` 85 + 86 + ### Product 87 + 88 + ```typescript 89 + import { Product, WithContext } from "schema-dts"; 90 + 91 + const productSchema: WithContext<Product> = { 92 + "@context": "https://schema.org", 93 + "@type": "Product", 94 + name: product.name, 95 + description: product.description, 96 + image: product.images, 97 + offers: { 98 + "@type": "Offer", 99 + price: product.price, 100 + priceCurrency: "USD", 101 + availability: "https://schema.org/InStock", 102 + }, 103 + aggregateRating: product.rating 104 + ? { 105 + "@type": "AggregateRating", 106 + ratingValue: product.rating.average, 107 + reviewCount: product.rating.count, 108 + } 109 + : undefined, 110 + }; 111 + ``` 112 + 113 + ## Implementation in Next.js 114 + 115 + ```typescript 116 + // Component to render JSON-LD 117 + function JsonLd({ data }: { data: WithContext<Thing> }) { 118 + return ( 119 + <script 120 + type="application/ld+json" 121 + dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} 122 + /> 123 + ) 124 + } 125 + 126 + // Usage in page 127 + export default function PostPage({ post }) { 128 + return ( 129 + <> 130 + <JsonLd data={generateArticleSchema(post)} /> 131 + <article>...</article> 132 + </> 133 + ) 134 + } 135 + ``` 136 + 137 + ## GROQ for Plain Text 138 + 139 + Structured data often needs plain text, not rich text: 140 + 141 + ```groq 142 + *[_type == "faq"]{ 143 + question, 144 + "answer": pt::text(answerRichText) // Convert Portable Text to plain string 145 + } 146 + ``` 147 + 148 + ## Testing Tools 149 + 150 + - [Google Rich Results Test](https://search.google.com/test/rich-results) 151 + - [Schema.org Validator](https://validator.schema.org/)
+153
.agents/skills/seo-aeo-best-practices/resources/technical-seo.md
··· 1 + # Technical SEO Checklist 2 + 3 + Essential technical SEO elements for modern web applications. 4 + 5 + ## Metadata 6 + 7 + ### Title Tags 8 + 9 + - Unique per page 10 + - 50-60 characters 11 + - Primary keyword near the beginning 12 + - Brand name at the end (optional) 13 + 14 + ### Meta Descriptions 15 + 16 + - Unique per page 17 + - 150-160 characters 18 + - Include call-to-action 19 + - Contain relevant keywords 20 + 21 + ### Open Graph 22 + 23 + ```html 24 + <meta property="og:title" content="Page Title" /> 25 + <meta property="og:description" content="Description" /> 26 + <meta property="og:image" content="https://example.com/image.jpg" /> 27 + <meta property="og:url" content="https://example.com/page" /> 28 + <meta property="og:type" content="article" /> 29 + ``` 30 + 31 + ### Sanity + Next.js Implementation 32 + 33 + ```typescript 34 + export async function generateMetadata({ params }): Promise<Metadata> { 35 + const { data } = await sanityFetch({ 36 + query: PAGE_QUERY, 37 + stega: false, // Critical: no stega in metadata 38 + }); 39 + 40 + return { 41 + title: data.seo?.title || data.title, 42 + description: data.seo?.description, 43 + openGraph: { 44 + images: data.seo?.image 45 + ? [ 46 + { 47 + url: urlFor(data.seo.image).width(1200).height(630).url(), 48 + width: 1200, 49 + height: 630, 50 + }, 51 + ] 52 + : [], 53 + }, 54 + robots: data.seo?.noIndex ? "noindex" : undefined, 55 + }; 56 + } 57 + ``` 58 + 59 + ## Sitemaps 60 + 61 + Dynamic sitemap from CMS content: 62 + 63 + ```typescript 64 + // app/sitemap.ts 65 + import { MetadataRoute } from "next"; 66 + 67 + export default async function sitemap(): Promise<MetadataRoute.Sitemap> { 68 + const pages = await client.fetch(` 69 + *[_type in ["page", "post"] && defined(slug.current) && seo.noIndex != true]{ 70 + "url": select( 71 + _type == "page" => "/" + slug.current, 72 + _type == "post" => "/blog/" + slug.current 73 + ), 74 + _updatedAt 75 + } 76 + `); 77 + 78 + return pages.map((page) => ({ 79 + url: `https://example.com${page.url}`, 80 + lastModified: new Date(page._updatedAt), 81 + changeFrequency: "weekly", 82 + priority: 0.8, 83 + })); 84 + } 85 + ``` 86 + 87 + ## Canonical URLs 88 + 89 + Prevent duplicate content issues: 90 + 91 + ```typescript 92 + export async function generateMetadata({ params }): Promise<Metadata> { 93 + return { 94 + alternates: { 95 + canonical: `https://example.com/${params.slug}`, 96 + }, 97 + }; 98 + } 99 + ``` 100 + 101 + ## Redirects 102 + 103 + CMS-managed redirects: 104 + 105 + ```typescript 106 + // next.config.ts 107 + async redirects() { 108 + const redirects = await client.fetch(` 109 + *[_type == "redirect" && isEnabled == true]{ 110 + source, 111 + destination, 112 + permanent 113 + } 114 + `) 115 + return redirects 116 + } 117 + ``` 118 + 119 + ## Performance 120 + 121 + [Core Web Vitals](https://web.dev/articles/defining-core-web-vitals-thresholds) 122 + impact rankings: 123 + 124 + - **LCP (Largest Contentful Paint):** < 2.5s 125 + - **INP (Interaction to Next Paint):** < 200ms 126 + - **CLS (Cumulative Layout Shift):** < 0.1 127 + 128 + ### Image Optimization (Next.js example) 129 + 130 + - Use `next/image` with Sanity URL builder 131 + - Serve WebP/AVIF formats 132 + - Implement LQIP blur placeholders 133 + - Set explicit dimensions 134 + 135 + ### Font Loading (Next.js example) 136 + 137 + ```typescript 138 + // Prevent layout shift 139 + import { Inter } from "next/font/google"; 140 + const inter = Inter({ subsets: ["latin"], display: "swap" }); 141 + ``` 142 + 143 + ## Robots.txt 144 + 145 + ``` 146 + # public/robots.txt 147 + User-agent: * 148 + Allow: / 149 + Disallow: /api/ 150 + Disallow: /studio/ 151 + 152 + Sitemap: https://example.com/sitemap.xml 153 + ```