|
| 1 | +# OpenGraph Image Generation System |
| 2 | + |
| 3 | +This document explains how the OG image generation system works and how to operate it. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The OG system generates social media preview images for all blog posts, videos, and other content. It was designed with two critical goals: |
| 8 | + |
| 9 | +1. **⚡ Performance** - OG images must be served extremely fast from filesystem cache |
| 10 | +2. **🎨 Quality & Uniformity** - Every page needs excellent, consistent OG images for maximum click-through rates |
| 11 | + |
| 12 | +The system uses a **two-step build-time process** to achieve these goals: |
| 13 | + |
| 14 | +1. **Metadata Extraction** → Extracts metadata from all MDX files to JSON cache |
| 15 | +2. **Image Generation** → Reads cache and generates OG images via API |
| 16 | + |
| 17 | +## Design Goals |
| 18 | + |
| 19 | +### 🚀 Ultra-Fast Serving |
| 20 | +- **Static file serving** - OG images are pre-generated and served from filesystem |
| 21 | +- **No runtime generation** - Zero API calls or processing when users share links |
| 22 | +- **CDN-optimized** - Images can be cached at edge locations for global speed |
| 23 | +- **Build-time validation** - Broken images caught before deployment |
| 24 | + |
| 25 | +### 🎯 Maximum Engagement |
| 26 | +- **Consistent branding** - All OG images use the same template and styling |
| 27 | +- **Rich content** - Images include title, description, and relevant visuals |
| 28 | +- **Social platform optimized** - Proper dimensions and formats for Twitter, LinkedIn, etc. |
| 29 | +- **Quality control** - Every page is guaranteed to have a beautiful OG image |
| 30 | + |
| 31 | +### 📈 Click-Through Impact |
| 32 | +Well-designed OG images are crucial for: |
| 33 | +- **Social media engagement** - Users stop scrolling when they see compelling previews |
| 34 | +- **Professional appearance** - Consistent branding builds trust and authority |
| 35 | +- **Content discovery** - Rich previews help users understand what they're clicking |
| 36 | +- **SEO benefits** - Social signals from shares improve search rankings |
| 37 | + |
| 38 | +## Architecture |
| 39 | + |
| 40 | +``` |
| 41 | +MDX Files → extract-metadata.js → metadata-cache.json → og-image-generator.js → Static OG Images → Fast Serving |
| 42 | +``` |
| 43 | + |
| 44 | +### Files |
| 45 | + |
| 46 | +- `scripts/extract-metadata.js` - Extracts metadata from all MDX files |
| 47 | +- `scripts/og-image-generator.js` - Generates OG images from metadata cache |
| 48 | +- `metadata-cache.json` - JSON cache of all content metadata (gitignored) |
| 49 | +- `public/og-images/` - Generated OG image files (served statically) |
| 50 | + |
| 51 | +## How It Works |
| 52 | + |
| 53 | +### 1. Metadata Extraction |
| 54 | + |
| 55 | +Parses all MDX files in `src/content/` and extracts metadata from `createMetadata()` calls: |
| 56 | + |
| 57 | +```bash |
| 58 | +node scripts/extract-metadata.js |
| 59 | +``` |
| 60 | + |
| 61 | +**What it extracts:** |
| 62 | +- Title, description, author, date |
| 63 | +- Image references and resolves import paths |
| 64 | +- Content type and slug |
| 65 | + |
| 66 | +**Output:** `metadata-cache.json` with all content metadata |
| 67 | + |
| 68 | +### 2. OG Image Generation |
| 69 | + |
| 70 | +Reads the metadata cache and generates images via the Next.js OG API: |
| 71 | + |
| 72 | +```bash |
| 73 | +# Generate all OG images |
| 74 | +npm run og:generate |
| 75 | + |
| 76 | +# Generate specific image |
| 77 | +npm run og:generate-for <slug> |
| 78 | + |
| 79 | +# With verbose logging |
| 80 | +npm run og:generate-for <slug> --verbose |
| 81 | +``` |
| 82 | + |
| 83 | +## Build Integration |
| 84 | + |
| 85 | +The system is integrated into the build process: |
| 86 | + |
| 87 | +```json |
| 88 | +{ |
| 89 | + "prebuild": "node scripts/extract-metadata.js && node scripts/check-metadata.js && node scripts/generate-collections.js" |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +**Build flow:** |
| 94 | +1. `extract-metadata.js` creates fresh metadata cache |
| 95 | +2. OG images are generated as needed during build |
| 96 | +3. Images are cached and only regenerated if missing |
| 97 | + |
| 98 | +## Manual Operations |
| 99 | + |
| 100 | +### Regenerate All Metadata |
| 101 | +```bash |
| 102 | +node scripts/extract-metadata.js |
| 103 | +``` |
| 104 | + |
| 105 | +### Regenerate All OG Images |
| 106 | +```bash |
| 107 | +npm run og:clean |
| 108 | +npm run og:generate |
| 109 | +``` |
| 110 | + |
| 111 | +### Generate Single OG Image |
| 112 | +```bash |
| 113 | +npm run og:generate-for your-blog-post-slug |
| 114 | +``` |
| 115 | + |
| 116 | +### Debug Metadata Extraction |
| 117 | +```bash |
| 118 | +# View extracted metadata for specific post |
| 119 | +cat metadata-cache.json | grep -A 10 "your-blog-post-slug" |
| 120 | +``` |
| 121 | + |
| 122 | +## Troubleshooting |
| 123 | + |
| 124 | +### "Wrong description in OG image" |
| 125 | +**Problem:** OG image shows text from code samples instead of actual metadata. |
| 126 | + |
| 127 | +**Solution:** The metadata extraction targets `createMetadata()` calls specifically. Regenerate the cache: |
| 128 | +```bash |
| 129 | +node scripts/extract-metadata.js |
| 130 | +rm public/og-images/problematic-slug.png |
| 131 | +npm run og:generate-for problematic-slug |
| 132 | +``` |
| 133 | + |
| 134 | +### "No metadata found in cache" |
| 135 | +**Problem:** Post exists but not in metadata cache. |
| 136 | + |
| 137 | +**Check:** |
| 138 | +1. Does the MDX file have `export const metadata = createMetadata({...})`? |
| 139 | +2. Is the metadata cache up to date? |
| 140 | + |
| 141 | +**Fix:** |
| 142 | +```bash |
| 143 | +node scripts/extract-metadata.js |
| 144 | +``` |
| 145 | + |
| 146 | +### "Metadata cache not found" |
| 147 | +**Problem:** OG generation fails because cache doesn't exist. |
| 148 | + |
| 149 | +**Fix:** |
| 150 | +```bash |
| 151 | +node scripts/extract-metadata.js |
| 152 | +``` |
| 153 | + |
| 154 | +### "OG generation fails" |
| 155 | +**Problem:** API errors when generating images. |
| 156 | + |
| 157 | +**Debug:** |
| 158 | +```bash |
| 159 | +# Check if dev server is running |
| 160 | +npm run og:generate-for <slug> --verbose |
| 161 | +``` |
| 162 | + |
| 163 | +## Development Notes |
| 164 | + |
| 165 | +- **Metadata cache is gitignored** - regenerated on each build |
| 166 | +- **Images are cached** - only regenerated if missing or forced |
| 167 | +- **Regex parsing is targeted** - only looks within `createMetadata()` calls |
| 168 | +- **Build-time validation** - metadata issues caught early |
| 169 | + |
| 170 | +## Performance |
| 171 | + |
| 172 | +The system is optimized for both build-time efficiency and runtime speed: |
| 173 | + |
| 174 | +### Build Performance |
| 175 | +- Metadata extraction: ~200ms for 130+ posts |
| 176 | +- OG generation: ~2-3s per image (cached after first generation) |
| 177 | +- Total build impact: minimal (only runs once per build) |
| 178 | + |
| 179 | +### Runtime Performance |
| 180 | +- **Zero server load** - All OG images served as static files |
| 181 | +- **Instant response** - No API calls or processing when pages are shared |
| 182 | +- **CDN-friendly** - Images cached globally for maximum speed |
| 183 | +- **SEO optimized** - Fast loading improves social platform crawling |
| 184 | + |
| 185 | +### Business Impact |
| 186 | +- **Higher engagement** - Fast-loading, beautiful previews increase click-through rates |
| 187 | +- **Better SEO** - Social shares with rich previews boost search rankings |
| 188 | +- **Professional brand** - Consistent, high-quality images build trust and authority |
| 189 | +- **Reduced bounce** - Users know what to expect before clicking, leading to better engagement |
0 commit comments