All skills
sanity-io avatar

/seo-aeo-best-practices

@ad50ea4 official
by Sanitysanity-io/agent-toolkit187 stars
30

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.

Use this Skill: https://skilld.dev/gh/sanity-io/agent-toolkit/seo-aeo-best-practices

This session only. Nothing lands on disk.

referencesstructured-data.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

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

import { Article, WithContext } from 'schema-dts'

const articleSchema: WithContext<Article> = {
  "@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

import { FAQPage, WithContext } from 'schema-dts'

const faqSchema: WithContext<FAQPage> = {
  "@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

import { Organization, WithContext } from 'schema-dts'

const orgSchema: WithContext<Organization> = {
  "@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

import { Product, WithContext } from 'schema-dts'

const productSchema: WithContext<Product> = {
  "@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

import { BreadcrumbList, WithContext } from 'schema-dts'

const breadcrumbSchema: WithContext<BreadcrumbList> = {
  "@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:

const pageSchema = {
  "@context": "https://schema.org",
  "@graph": [
    generateArticleSchema(post),      // No @context needed here
    generateBreadcrumbSchema(breadcrumbs),
    generateOrganizationSchema(),
  ]
}

Implementation in Next.js

// 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<Thing> }) {
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
    />
  )
}

// Usage in page
export default function PostPage({ post }) {
  return (
    <>
      <JsonLd data={generateArticleSchema(post)} />
      <article>...</article>
    </>
  )
}

GROQ for Plain Text

Structured data often needs plain text, not rich text:

*[_type == "faq"]{
  question,
  "answer": pt::text(answerRichText)  // Convert Portable Text to plain string
}

Testing Tools

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides comprehensive best practices and code templates for Search Engine Optimization (SEO) and Answer Engine Optimization (AEO). It includes Sanity CMS schemas, Next.js metadata implementations, and JSON-LD structured data patterns for enhancing content visibility for search engines and AI assistants. No security issues were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    5 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at ad50ea4. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 6 months ago
  • SEO
  • aeo
  • metadata
  • structured-data
  • json-ld
  • open-graph
  • robots.txt
  • hreflang
  • eeat
  • schema-markup

README badge

README badge for sanity-io/agent-toolkit/seo-aeo-best-practices

Provides SEO and AEO best practices for metadata, Open Graph, sitemaps, robots.txt, hreflang, JSON-LD structured data, and EEAT guidelines. Use this when implementing page SEO, technical SEO, schema markup, or optimizing content for both search engines and AI answer engines like ChatGPT and Perplexity.

Generated from the current SKILL.md.

Does this skill cover both traditional SEO and AI answer engine optimization?
Yes. It includes SEO best practices for search engines and AEO practices for AI assistants like ChatGPT and Perplexity, plus Google's EEAT framework for content quality.
What structured data formats does this skill document?
It covers JSON-LD patterns including Article, FAQ, Breadcrumb, and Product schema, with implementation guidance in the structured-data reference.
Does this skill provide technical SEO guidance like sitemaps and robots.txt?
Yes. It includes a technical SEO checklist covering metadata, sitemaps, hreflang tags, and robots.txt configuration.
What is EEAT and how does this skill use it?
EEAT (Experience, Expertise, Authoritativeness, Trustworthiness) is Google's framework for evaluating content quality. The skill includes EEAT implementation principles and author schema patterns to meet these guidelines.

Generated from the current SKILL.md. These answers refresh after source changes.