This guide explains how to properly implement metadata for bulletproof SEO across all content types in the Chainlink documentation. Our SEO system uses both HTML meta tags and JSON-LD structured data to ensure optimal search engine visibility and rich result display.
- Overview
- SEO Architecture
- Content Types & Templates
- Metadata Schema Reference
- Best Practices
- Validation & Testing
- Troubleshooting
Our documentation uses a comprehensive dual SEO approach:
- HTML Meta Tags: Traditional SEO elements (title, description, OpenGraph, Twitter Cards)
- JSON-LD Structured Data: Schema.org compliant structured data for rich snippets and enhanced search results
Both systems work together automatically when you provide proper frontmatter metadata.
This system supports all content types:
- Quickstarts: Step-by-step getting started guides
- Tutorials: In-depth learning content
- Concepts: Educational explanations
- Guides: How-to documentation
- API References: Technical documentation
Content (MDX) with Frontmatter
↓
Layout System (QuickstartLayout, DocsLayout, etc.)
↓
BaseLayout
↓
HeadSEO Component
↓
- HTML meta tags generation
- JSON-LD structured data generation
↓
Search Engine Crawler
Every page automatically receives:
HTML Meta Tags:
<title>Page Title | Chainlink Documentation</title>
<meta name="description" content="..." />
<link rel="canonical" href="..." />
<meta property="og:title" content="..." />
<meta property="og:type" content="article" />
<meta property="og:description" content="..." />
<meta name="twitter:card" content="summary_large_image" />JSON-LD Structured Data:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": ["HowTo", "TechArticle"],
"name": "Deploy Your First Smart Contract",
"description": "Learn to deploy smart contracts in 10 minutes",
"totalTime": "PT10M",
"author": { "@type": "Organization", "name": "Chainlink Labs" },
"publisher": { "@type": "Organization", "name": "Chainlink Documentation" }
}
</script>- Non-versioned pages can override canonical with
metadata.canonical.- Relative values are resolved to absolute URLs using the site base.
- Versioned API reference pages set canonicals/alternates via the version head component.
- Latest version:
rel="canonical"; other versions:rel="alternate". hreflangis not used for versioning.
- Latest version:
og:typeis set contextually:website: for/,/ccip,/ccip/directory*,/data-feeds,/vrf,/chainlink-functions,/chainlink-automation,/chainlink-local,/resources.article: for all other pages.
File Location: src/content/quickstarts/
Frontmatter Template:
---
title: "Deploy Your First Smart Contract"
description: "Write and deploy a smart contract in 10 minutes using Remix IDE"
image: "quickstart-deploy.webp"
products: ["general"]
time: "10 minutes"
requires: "MetaMask wallet"
---Generated Schema: HowTo + TechArticle with quickstart-specific properties
totalTime: Parsed fromtimefield (e.g., "10 minutes" → "PT10M")supply: Generated fromrequiresfieldlearningResourceType: "Quickstart"
File Location: src/content/[product]/tutorials/
Frontmatter Template:
---
section: ccip
title: "Transfer Tokens Cross-Chain"
metadata:
description: "Learn how to transfer tokens between blockchains using CCIP"
excerpt: "ccip cross-chain token transfer tutorial hardhat solidity"
estimatedTime: "45 minutes"
difficulty: "intermediate"
image: "/images/ccip-tutorial.png"
whatsnext:
"Build a cross-chain dApp": "/ccip/tutorials/cross-chain-dapp"
---Generated Schema: HowTo + TechArticle with tutorial properties
totalTime: FromestimatedTimefieldeducationalLevel: FromdifficultyfieldlearningResourceType: "Tutorial"
File Location: src/content/[product]/concepts/
Frontmatter Template:
---
section: ccip
title: "CCIP Architecture Overview"
metadata:
description: "Understanding the architecture of Chainlink CCIP"
excerpt: "ccip architecture cross-chain protocol intermediate concepts"
difficulty: "intermediate"
image: "/images/ccip-architecture.png"
---Generated Schema: TechArticle + LearningResource
educationalLevel: Fromdifficultyfieldteaches: Derived from content type and product (e.g., "Concept for CCIP")learningResourceType: "Concept"
File Location: src/content/[product]/guides/ or similar
Frontmatter Template:
---
section: vrf
title: "Generate Random Numbers"
metadata:
description: "Step-by-step guide to implement VRF in your smart contract"
excerpt: "vrf random numbers smart contract solidity guide"
estimatedTime: "30 minutes"
difficulty: "beginner"
---Generated Schema: HowTo + TechArticle
- Similar to tutorials but classified as "Guide"
File Location: src/content/[product]/api-reference/
Frontmatter Template:
---
section: ccip
title: "Router Interface"
metadata:
description: "Complete API reference for CCIP Router contract"
excerpt: "ccip router api interface solidity smart contract reference"
version: "1.6.0"
datePublished: "2024-01-15T10:00:00Z"
lastModified: "2024-03-10T14:30:00Z"
---Generated Schema: APIReference + TechArticle
version: API version from metadataprogrammingModel: Auto-detected (e.g., "Smart Contract")targetPlatform: "Blockchain"
All Content Types:
title: Page title (string)metadata.description: Meta description, 150-160 characters (string)
Enhanced SEO:
metadata.excerpt: Keywords for search optimization (string)metadata.image: Social sharing image path (string)metadata.estimatedTime: Reading/completion time (string, e.g., "30 minutes")metadata.difficulty: Content difficulty level ("beginner" | "intermediate" | "advanced")
Quickstart Specific:
time: Completion time (string, e.g., "10 minutes")requires: Prerequisites (string)products: Product array (string[])
Advanced SEO:
metadata.canonical: Canonical URL for duplicate content (string)metadata.version: Version for API references (string)metadata.lastModified: Last update date, ISO format (string)metadata.datePublished: Original publication date, ISO format (string)
Time Formats:
- Input: "10 minutes", "1 hour", "30 mins", "2 hours"
- Output: ISO 8601 duration (PT10M, PT1H, PT30M, PT2H)
Difficulty Levels:
- Must be one of: "beginner", "intermediate", "advanced"
- Maps to Schema.org
educationalLevel
Description Length:
- Optimal: 150-160 characters
- Maximum: 300 characters
- Should include primary keywords
Excerpt Keywords:
- Space-separated keywords
- Include product name, main concepts, target audience
- Example: "ccip cross-chain token transfer tutorial hardhat solidity"
Date Fields (Optional but Recommended):
datePublished: Use for first publication (ISO 8601 format: "2024-01-15T10:00:00Z")lastModified: Update when content changes significantly- Falls back to current date if not provided
Good Example:
description: "Learn how to transfer tokens between Ethereum and Polygon using Chainlink CCIP in this step-by-step tutorial"Why it works:
- Clearly states the goal ("transfer tokens")
- Mentions specific networks ("Ethereum and Polygon")
- Includes the product ("Chainlink CCIP")
- Indicates content type ("step-by-step tutorial")
- Within 150-160 character limit
Structure: [product] [main-concept] [secondary-concepts] [content-type] [tools] [audience]
Example:
excerpt: "ccip cross-chain token transfer tutorial hardhat solidity intermediate"Quickstarts: 5-15 minutes
- Quick setup or simple implementation
- Minimal explanation, focus on doing
Tutorials: 30-60 minutes
- Comprehensive learning experience
- Includes context and explanation
Concepts: 10-20 minutes
- Reading and understanding time
- No hands-on implementation
Path Format:
- Standard pages:
metadata.imageshould be an absolute path like/images/[product]/[descriptive-name].png. - Quickstarts:
frontmatter.imageis a filename resolved to/images/quickstarts/feature/{filename}.
Requirements:
- Minimum 1200x630px for social sharing
- Prefer PNG or JPG for broad preview compatibility
- WebP is acceptable, but some bots preview PNG/JPG more reliably
- Avoid animated GIFs for social previews (often heavy; many platforms show only the first frame)
- Include alt text context in filename
Note: The system falls back to the Chainlink logo if no custom image is provided. The current implementation sets og:image:type to image/png; using PNG avoids type mismatches.
Use consistent section values:
ccip: Cross-Chain Interoperability Protocolvrf: Verifiable Random Functionautomation: Chainlink AutomationdataFeeds: Data FeedschainlinkFunctions: Chainlink Functions
Google Rich Results Test:
- Build your page locally
- Visit Rich Results Test
- Enter your page URL or paste HTML
- Verify structured data recognition
Schema.org Validator:
- Visit Schema.org Validator
- Paste your JSON-LD structured data
- Check for compliance issues
Missing Required Properties:
Error: Missing required property 'headline' for type 'TechArticle'
Solution: Ensure title is provided in frontmatter
Invalid Time Format:
Error: Invalid duration format 'thirty minutes'
Solution: Use numeric format like "30 minutes"
Missing Description:
Error: Missing required property 'description'
Solution: Add metadata.description to frontmatter
Check 1: Frontmatter Format Ensure proper YAML syntax:
---
title: "Your Title"
metadata:
description: "Your description"
# More fields...
---Check 2: Required Fields
Verify both title and metadata.description are present.
Check 3: Build Process
Run npm run build and check for errors in console.
Issue: Page shows "undefined" in title or description Solution: Check that frontmatter includes required fields and follows the correct nested structure for your content type.
Issue: Google doesn't show rich snippets in search results Causes:
- New content (can take weeks to appear)
- Missing required structured data properties
- Content quality doesn't meet Google's standards
Solution: Use validation tools and ensure content provides real value to users.
Issue: Uncertain which content type to use Guidelines:
- Quickstart: Get something working quickly (≤15 minutes)
- Tutorial: Learn concepts thoroughly (30+ minutes)
- Guide: Solve a specific problem (varies)
- Concept: Understand how something works (reading time)
Issue: Concerns about SEO system affecting page load Reality: Minimal impact
- JSON-LD scripts are small (typically <2KB)
- Processed at build time (no client-side runtime cost)
- Social image existence is validated at build time; no client-side requests
- Automatic fallbacks prevent missing data
When updating existing content for better SEO:
- Add
metadata.description(150-160 characters) - Verify
titleis descriptive and unique
- Add
metadata.excerpt(relevant keywords) - Add
metadata.estimatedTimefor tutorials/quickstarts - Add
metadata.difficultyfor learning content - Add
metadata.imagefor custom social sharing (optional - falls back to logo)
- Add
metadata.datePublishedfor new content - Add
metadata.lastModifiedwhen updating content - Add
metadata.versionfor API references
✅ Fully Implemented Features:
- Automatic image fallbacks (Chainlink logo)
- Smart date handling (metadata with fallbacks)
- API version detection (metadata + URL)
- Enhanced organization schema
- 100% Schema.org compliance
- Rich results eligibility
System Benefits:
- No missing images in social sharing
- Proper date attribution for content freshness
- Enhanced rich results display
- Improved search engine understanding
- Professional fallbacks for all content
Following this guide ensures consistent, high-quality SEO implementation across all Chainlink documentation content types with bulletproof fallbacks and enhanced rich result eligibility.