the home site for me: also iteration 3 or 4 of my site
1import puppeteer from "puppeteer"; 2import { readdir, mkdir } from "node:fs/promises"; 3 4const template = await Bun.file("tools/og.html").text(); 5 6const browser = await puppeteer.launch(); 7 8async function og( 9 postname: string, 10 type: string, 11 by: string | undefined, 12 outputPath: string, 13 width = 1200, 14 height = 630, 15) { 16 const page = await browser.newPage(); 17 18 await page.setViewport({ width, height }); 19 20 await page.setContent( 21 template 22 .toString() 23 .replace("{{postname}}", postname) 24 .replace("{{type}}", type) 25 .replace("{{by}}", by || ""), 26 ); 27 28 await page.screenshot({ path: outputPath }); 29} 30 31async function fileExists(path: string): Promise<boolean> { 32 try { 33 await Bun.file(path); 34 return true; 35 } catch (e) { 36 return false; 37 } 38} 39 40try { 41 // check if the public/blog folder exists 42 // if not exit 43 // if it does, get all the folders and then get the title tag from the index.html 44 45 if (!(await fileExists("public/"))) { 46 console.error("public/ does not exist"); 47 process.exit(1); 48 } 49 50 // read all the files in the current directory filtering for index.htmls 51 const files = (await readdir("public/", { recursive: true })).filter((file) => 52 file.endsWith("index.html"), 53 ); 54 55 const directories = new Set( 56 files.map((file) => file.replace("index.html", "")), 57 ); 58 59 const existing = (await readdir("static/")).filter((file) => 60 directories.has(file), 61 ); 62 63 // create not existing 64 for (const dir of directories) { 65 if (!existing.includes(dir)) { 66 await mkdir(`static/${dir.split("/").slice(0, -1).join("/")}`, { 67 recursive: true, 68 }); 69 } 70 } 71 72 console.log("Generating OG images for", files.length, "files"); 73 74 // for each file, get the title tag from the index.html 75 for (const file of files) { 76 const index = await Bun.file(`public/${file}`).text(); 77 const title = index.match(/<title>(.*?)<\/title>/)[1]; 78 let type = "Page"; 79 let by: string | undefined; 80 switch (file.split("/")[0]) { 81 case "blog": 82 type = "Blog"; 83 if (file.split("/")[1] !== "index.html") { 84 by = "<p>A post ... yeah thats about it</p>"; 85 } else { 86 by = "<p>All authored by me ... or are they???</p>"; 87 } 88 break; 89 case "verify": 90 type = "Slash Page"; 91 by = "<p>So you can stalk me 💀</p>"; 92 break; 93 case "pfp": 94 type = "Slash Page"; 95 by = "<p>Want to stare at my pretty face?</p>"; 96 break; 97 case "tags": 98 if (file.split("/")[1] === "index.html") { 99 type = "Tags"; 100 by = "<p>A total archive!</p>"; 101 } else { 102 type = "Tag"; 103 by = "<p>Find more posts like this!</p>"; 104 } 105 break; 106 case "index.html": 107 type = "Root"; 108 by = "<p>Where it all begins</p>"; 109 break; 110 } 111 112 console.log("Generating OG for", file, "title:", title, "with type:", type); 113 await og(title, type, by, `static/${file.replace("index.html", "og.png")}`); 114 } 115} catch (e) { 116 console.error(e); 117} finally { 118 await browser.close(); 119}