| name | seo |
| description | SEO audit and structured data patterns - meta tags, Open Graph, JSON-LD schema, Core Web Vitals. Use for marketing sites and e-commerce. |
| triggers | ["seo","meta tags","open graph","structured data","sitemap"] |
| allowed-tools | Read, Grep, Glob, Edit, Write, Bash |
| model | opus |
| user-invocable | true |
SEO & Structured Data
Based on coreyhaines31/marketingskills (MIT). Merged from seo-audit and schema-markup skills.
1. Meta Tags & Open Graph
Title Tags
- 50-60 characters, primary keyword near the beginning
- Unique per page, compelling and click-worthy
- Brand name at end:
Primary Keyword | Brand
Meta Descriptions
- 150-160 characters with primary keyword
- Clear value proposition and call to action
- Unique per page (never auto-generated filler)
Open Graph & Twitter Cards
<meta property="og:title" content="Page Title" />
<meta property="og:description" content="Page description" />
<meta property="og:image" content="https://example.com/og-image.jpg" />
<meta property="og:url" content="https://example.com/page" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Page Title" />
<meta name="twitter:description" content="Page description" />
<meta name="twitter:image" content="https://example.com/twitter-image.jpg" />
OG images: 1200x630px. Twitter images: 1200x600px.
2. JSON-LD Schema Markup
Use JSON-LD format (Google recommended). Place in <head> or end of <body>.
Common Schema Types
| Type | Use For | Required Properties |
|---|
| Organization | Company homepage | name, url |
| Product | Product pages | name, image, offers |
| Article | Blog posts | headline, image, datePublished, author |
| FAQPage | FAQ content | mainEntity (Q&A array) |
| BreadcrumbList | Any page with breadcrumbs | itemListElement |
| LocalBusiness | Local business pages | name, address |
Product Schema (E-commerce)
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product Name",
"image": "https://example.com/product.jpg",
"description": "Product description",
"sku": "SKU-001",
"brand": { "@type": "Brand", "name": "Brand Name" },
"offers": {
"@type": "Offer",
"price": "29.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://example.com/product"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "42"
}
}
Organization Schema
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Company Name",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"sameAs": [
"https://twitter.com/company",
"https://linkedin.com/company/company"
]
}
Multiple Types with @graph
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Organization", "name": "...", "url": "..." },
{ "@type": "WebSite", "name": "...", "url": "..." },
{ "@type": "BreadcrumbList", "itemListElement": [...] }
]
}
3. Technical SEO
Sitemap & Robots
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-01-15</lastmod>
<priority>1.0</priority>
</url>
</urlset>
# public/robots.txt
User-agent: *
Allow: /
Disallow: /api/
Disallow: /admin/
Sitemap: https://example.com/sitemap.xml
Canonical URLs
- Every page needs a canonical tag (self-referencing for unique pages)
- Consistent www vs non-www, trailing slash, HTTP vs HTTPS
- Prevents duplicate content issues
Redirects
- Use 301 for permanent redirects (passes SEO value)
- Fix redirect chains (A -> B -> C should be A -> C)
- Handle trailing slashes consistently
Core Web Vitals
- LCP (Largest Contentful Paint): < 2.5s
- INP (Interaction to Next Paint): < 200ms
- CLS (Cumulative Layout Shift): < 0.1
4. Next.js SEO
Static Metadata
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Page Title | Brand',
description: 'Page description for search results',
openGraph: {
title: 'Page Title',
description: 'OG description',
images: [{ url: '/og-image.jpg', width: 1200, height: 630 }],
},
twitter: {
card: 'summary_large_image',
},
};
Dynamic Metadata
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const product = await getProduct(params.slug);
return {
title: `${product.name} | Brand`,
description: product.description,
openGraph: {
images: [{ url: product.image }],
},
};
}
JSON-LD in Next.js
export default function ProductPage({ product }: Props) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
offers: {
'@type': 'Offer',
price: product.price,
priceCurrency: 'USD',
},
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{}
</>
);
}
5. Audit Checklist
Before Launch
Validation Tools
E-commerce Specifics