47 lines
1.7 KiB
JavaScript
47 lines
1.7 KiB
JavaScript
/**
|
||
* OG Image generator — converts og-image.svg to og-image.png (1200x630).
|
||
* Run from project root: node scripts/generate-og-image.mjs
|
||
*
|
||
* Generates:
|
||
* frontend/public/og-image.png (1200×630 — required by OG / Twitter Card)
|
||
*
|
||
* Note: SVG images are NOT supported by most OG crawlers (Facebook, Slack,
|
||
* WhatsApp, Google Search Console…). This script produces the required PNG.
|
||
*/
|
||
|
||
import { readFileSync, writeFileSync } from 'fs';
|
||
import { join, dirname } from 'path';
|
||
import { fileURLToPath } from 'url';
|
||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||
const ROOT = join(__dirname, '..');
|
||
const PUBLIC = join(ROOT, 'frontend', 'public');
|
||
|
||
// ── install @resvg/resvg-js on the fly if missing ──────────────────
|
||
async function ensureDep(pkg) {
|
||
try { return await import(pkg); } catch {}
|
||
console.log(`Installing ${pkg}…`);
|
||
const { execSync } = await import('child_process');
|
||
execSync(`npm install --no-save ${pkg}`, { stdio: 'inherit', cwd: ROOT });
|
||
return await import(pkg);
|
||
}
|
||
|
||
const { Resvg } = await ensureDep('@resvg/resvg-js');
|
||
|
||
// ── render og-image.svg at 1200 px wide ────────────────────────────
|
||
const svgPath = join(PUBLIC, 'og-image.svg');
|
||
const svgSrc = readFileSync(svgPath);
|
||
|
||
const resvg = new Resvg(svgSrc, {
|
||
fitTo: { mode: 'width', value: 1200 },
|
||
font: { loadSystemFonts: false },
|
||
});
|
||
|
||
const pngData = resvg.render();
|
||
const pngBuffer = pngData.asPng();
|
||
|
||
writeFileSync(join(PUBLIC, 'og-image.png'), pngBuffer);
|
||
|
||
console.log(`✓ og-image.png (1200×auto)`);
|
||
console.log('\nDone. og-image.png is ready in frontend/public/');
|