SEO & Metadata
Rich metadata and Open Graph images for improved discoverability
Source: apps/web/content/docs/features/seo-metadata.mdx
Comprehensive SEO optimization with rich metadata, Open Graph images, and search engine discoverability.
Overview
AI Web Feeds implements Next.js Metadata API for:
Features
✨ What's Included
- Dynamic OG Images - Unique images generated for each documentation page
- Rich Metadata - Complete title, description, keywords, and author information
- Twitter Cards - Summary cards with large images
- Canonical URLs - Proper canonical link tags
- Structured Data - JSON-LD for better search results
- Sitemap - Auto-generated XML sitemap
- Robots.txt - Search engine crawling rules with AI bot support
- PWA Manifest - Progressive Web App configuration
- RSS Discovery - Feed links in HTML head
Open Graph Images
Dynamic Page Images
Every documentation page gets a unique OG image:
export function getPageImage(page: InferPageType<typeof source>) {
const segments = [...page.slugs, "image.png"];
return {
segments,
url: `/og/docs/${segments.join("/")}`,
};
}Image Design
Custom-designed OG images with:
- Dark theme - Modern dark background with gradient accents
- Brand identity - Logo and site name
- Page title - Large, readable typography
- Description - Supporting text for context
- Category badge - Visual categorization
- Site URL - Domain attribution
Example URLs
/og/docs/image.pngMain documentation landing page OG image
/og/docs/features/pdf-export/image.pngPDF Export feature page OG image
/og/docs/guides/quick-reference/image.pngQuick Reference guide OG image
Image Specifications
| Property | Value |
|---|---|
| Width | 1200px |
| Height | 630px |
| Format | PNG |
| Generation | Static at build time |
| Caching | Permanent (revalidate = false) |
Metadata Structure
Root Layout
Site-wide metadata in app/layout.tsx:
export const metadata: Metadata = {
metadataBase: new URL(baseUrl),
title: {
default: 'AI Web Feeds - RSS/Atom Feeds for AI Agents',
template: '%s | AI Web Feeds',
},
description: 'Curated RSS/Atom feeds optimized for AI agents...',
keywords: ['AI', 'RSS feeds', 'Atom feeds', ...],
authors: [{ name: 'Wyatt Walsh', url: '...' }],
openGraph: {
type: 'website',
locale: 'en_US',
url: baseUrl,
siteName: 'AI Web Feeds',
images: [{ url: '/og-image.png', width: 1200, height: 630 }],
},
twitter: {
card: 'summary_large_image',
creator: '@wyattowalsh',
},
robots: {
index: true,
follow: true,
googleBot: {
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
};Documentation Pages
Dynamic metadata for each page in app/docs/[[...slug]]/page.tsx:
export async function generateMetadata(
props: PageProps
): Promise<Metadata> {
const page = source.getPage(params.slug);
return {
title: page.data.title,
description: page.data.description,
keywords: ['documentation', 'AI', ...],
openGraph: {
type: 'article',
title: page.data.title,
url: pageUrl,
images: [{ url: imageUrl, width: 1200, height: 630 }],
},
twitter: {
card: 'summary_large_image',
title: page.data.title,
images: [imageUrl],
},
alternates: {
canonical: pageUrl,
types: {
'application/rss+xml': '/docs/rss.xml',
'application/atom+xml': '/docs/atom.xml',
},
},
};
}Sitemap
Auto-generated XML sitemap at /sitemap.xml:
export default function sitemap(): MetadataRoute.Sitemap {
const pages = source.getPages();
return pages.map((page) => ({
url: `${baseUrl}${page.url}`,
lastModified: new Date(),
changeFrequency: "weekly",
priority: 0.8,
}));
}Sitemap Features
- ✅ All documentation pages included
- ✅ Proper priority levels
- ✅ Change frequency hints
- ✅ Last modified dates
- ✅ Auto-updates on build
Access Sitemap
curl https://ai-web-feeds.vercel.app/sitemap.xmlRobots.txt
Custom robots.txt with AI crawler support:
User-agent: *
Allow: /
Disallow: /api/
Disallow: /_next/
Disallow: /static/
User-agent: GPTBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: anthropic-ai
Allow: /
User-agent: ClaudeBot
Allow: /
Sitemap: https://ai-web-feeds.vercel.app/sitemap.xmlAI Crawler Support
Explicitly allows common AI crawlers:
- GPTBot - OpenAI's web crawler
- ChatGPT-User - ChatGPT browsing
- Google-Extended - Google's AI training crawler
- anthropic-ai - Anthropic's crawler
- ClaudeBot - Claude's web crawler
PWA Manifest
Progressive Web App configuration:
{
"name": "AI Web Feeds - RSS/Atom Feeds for AI Agents",
"short_name": "AI Web Feeds",
"description": "Curated RSS/Atom feeds optimized for AI agents",
"start_url": "/",
"display": "standalone",
"background_color": "#0a0a0a",
"theme_color": "#667eea",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}Social Media Preview
How It Looks
When shared on social media, links display:
Twitter/X
- Large image (1200x630)
- Page title
- Description
- Site name
- Creator handle
- Large image
- Page title
- Description
- Site URL
Slack/Discord
- Rich embed with image
- Title and description
- Site information
Testing Social Cards
- Enter page URL
- Click "Preview card"
- Verify image and text
- Enter page URL
- Click "Inspect"
- Review preview
Use Facebook Sharing Debugger:
- Enter page URL
- Click "Debug"
- Scrape again if needed
Search Engine Optimization
Google Search Features
Optimized for:
- Rich snippets - Enhanced search results
- Knowledge graph - Structured data integration
- Image preview - Large image thumbnails
- Site links - Auto-generated navigation
- Breadcrumbs - Clear page hierarchy
Verification
Add verification codes in app/layout.tsx:
verification: {
google: 'your-google-verification-code',
yandex: 'your-yandex-verification-code',
bing: 'your-bing-verification-code',
}Implementation
File Structure
app/
├── layout.tsx # Root metadata
├── manifest.ts # PWA manifest
├── robots.ts # Robots.txt
├── sitemap.ts # XML sitemap
├── og-image.png/
│ └── route.tsx # Homepage OG image
├── (home)/
│ └── page.tsx # Homepage metadata
├── docs/
│ └── [[...slug]]/
│ └── page.tsx # Dynamic page metadata
└── og/
└── docs/
└── [...slug]/
└── route.tsx # Dynamic OG images
lib/
└── source.ts # getPageImage helperKey Functions
Get Page Image URL
const image = getPageImage(page);
// { segments: ['features', 'pdf-export', 'image.png'],
// url: '/og/docs/features/pdf-export/image.png' }Generate Metadata
export async function generateMetadata(props): Promise<Metadata> {
const page = source.getPage(params.slug);
return {
title: page.data.title,
openGraph: { images: getPageImage(page).url },
};
}Best Practices
1. Title Templates
Use templates for consistent branding:
title: {
default: 'AI Web Feeds',
template: '%s | AI Web Feeds',
}Results in:
- Homepage: "AI Web Feeds"
- Docs page: "Getting Started | AI Web Feeds"
2. Description Length
Keep descriptions under 160 characters:
description: "Clear, concise description under 160 characters";3. Image Optimization
- Use 1200x630 for OG images (1.91:1 ratio)
- Keep file sizes under 1MB
- Use high-contrast text
- Test on multiple platforms
4. Canonical URLs
Always set canonical URLs:
alternates: {
canonical: pageUrl,
}5. Keywords
Include relevant keywords:
keywords: ["specific", "relevant", "keywords"];Troubleshooting
OG Images Not Showing
bash pnpm build Social Media Cache
If old images persist:
- Clear platform cache using their debug tools
- Add query parameter:
?v=2to force refresh - Wait 24-48 hours for automatic cache expiry
Missing Metadata
Check browser dev tools:
# View page source
curl https://ai-web-feeds.vercel.app/docs | grep -i "og:"
curl https://ai-web-feeds.vercel.app/docs | grep -i "twitter:"Expected tags:
<meta property="og:title" content="..." />
<meta property="og:description" content="..." />
<meta property="og:image" content="..." />
<meta name="twitter:card" content="summary_large_image" />Testing
Verify Metadata
Check HTML Head
View page source and verify tags:
curl https://ai-web-feeds.vercel.app/docs | head -100Test OG Images
Visit image URLs directly:
/og-image.png
/og/docs/image.png
/og/docs/features/pdf-export/image.pngValidate Sitemap
curl https://ai-web-feeds.vercel.app/sitemap.xmlCheck Robots.txt
curl https://ai-web-feeds.vercel.app/robots.txtSEO Audit Tools
- Google Search Console
- Bing Webmaster Tools
- Lighthouse (Chrome DevTools)
- PageSpeed Insights
Performance
Build-Time Generation
All OG images generated during build:
- Development: Images generated on-demand
- Production: All images pre-rendered
- Caching: Permanent (
revalidate = false)
Size Optimization
| Asset | Size |
|---|---|
| OG Image (PNG) | ~50-100KB |
| Sitemap XML | ~5-10KB |
| Manifest JSON | ~1KB |
| Robots.txt | ~500B |
Related Documentation
- RSS Feeds - Feed discovery and metadata
- AI Integration - AI crawler support
- Quick Reference - Metadata endpoints