import { chromium } from 'playwright';
import { writeFileSync, mkdirSync, readFileSync } from 'fs';
import { join } from 'path';
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || 'https://skills.palebluedot.live';
const SCREENSHOTS_DIR = './screenshots';
const OG_DIR = './apps/web/public/og';
// Read logo SVG and encode for inline use
const logoSvg = readFileSync('./apps/web/public/logo.svg', 'utf-8');
const logoBase64 = Buffer.from(logoSvg).toString('base64');
// Screenshots to capture (English locale, scroll past header)
const SCREENSHOTS = [
{ name: '01-homepage', url: '/en', scrollY: 0, description: 'Homepage with hero and featured skills' },
{ name: '02-browse', url: '/en/browse', scrollY: 80, description: 'Browse page with filters and skill cards' },
{ name: '03-skill-detail', url: '/en/skill/anthropics/skills/pdf', scrollY: 60, description: 'Skill detail page' },
{ name: '04-categories', url: '/en/categories', scrollY: 80, description: 'Categories page' },
{ name: '05-search-results', url: '/en/browse?q=python', scrollY: 80, description: 'Search results' },
];
async function createOGImage(page) {
console.log('Creating OG image (1200x630)...');
// Create a branded OG image with logo and evergreen stats
const ogHTML = `
SkillHub
Open-Source Marketplace for AI Agent Skills
Claude Code
Codex CLI
GitHub Copilot
`;
await page.setContent(ogHTML);
await page.setViewportSize({ width: 1200, height: 630 });
await page.screenshot({
path: join(OG_DIR, 'og-default.png'),
type: 'png'
});
console.log(' Saved: og-default.png (1200x630)');
}
async function captureScreenshots(page) {
console.log('\nCapturing marketing screenshots (English)...');
for (const shot of SCREENSHOTS) {
console.log(' Capturing: ' + shot.name + ' - ' + shot.description);
try {
await page.goto(BASE_URL + shot.url, {
waitUntil: 'networkidle',
timeout: 30000
});
// Wait for content to load
await page.waitForTimeout(1500);
// Scroll past header if specified
if (shot.scrollY > 0) {
await page.evaluate((scrollY) => {
window.scrollTo(0, scrollY);
}, shot.scrollY);
await page.waitForTimeout(500);
}
await page.screenshot({
path: join(SCREENSHOTS_DIR, shot.name + '.png'),
fullPage: false,
});
console.log(' Saved: ' + shot.name + '.png');
} catch (error) {
console.error(' Error capturing ' + shot.name + ': ' + error.message);
}
}
}
async function main() {
console.log('=== SkillHub Marketing Assets Generator ===\n');
const browser = await chromium.launch({ headless: true });
// Create context with HiDPI settings for screenshots
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 2, // Retina quality
locale: 'en-US', // Force English
});
const page = await context.newPage();
// Create OG Image first
await createOGImage(page);
// Capture screenshots from live site (English)
await captureScreenshots(page);
await browser.close();
console.log('\n=== Done! ===');
console.log('\nOG Image: ' + OG_DIR + '/og-default.png');
console.log('Screenshots: ' + SCREENSHOTS_DIR + '/');
}
main().catch(console.error);