docs/inject-og-tags.ts 2.6 K raw
1
#!/usr/bin/env bun
2
3
import { readdirSync, statSync } from "node:fs";
4
import { join } from "node:path";
5
6
const distDir = "./docs/dist";
7
const ogImageUrl = "https://sequoia.pub/og.png";
8
9
// Function to recursively find all HTML files
10
function findHtmlFiles(dir: string): string[] {
11
	const files: string[] = [];
12
	const entries = readdirSync(dir);
13
14
	for (const entry of entries) {
15
		const fullPath = join(dir, entry);
16
		const stat = statSync(fullPath);
17
18
		if (stat.isDirectory()) {
19
			files.push(...findHtmlFiles(fullPath));
20
		} else if (entry.endsWith(".html")) {
21
			files.push(fullPath);
22
		}
23
	}
24
25
	return files;
26
}
27
28
// Function to inject OG image meta tags
29
async function injectOgImageTags(filePath: string) {
30
	const file = Bun.file(filePath);
31
	const content = await file.text();
32
33
	// Check if og:image already exists
34
	if (content.includes('property="og:image"')) {
35
		console.log(`⏭️  Skipping ${filePath} - og:image already exists`);
36
		return;
37
	}
38
39
	// Find the position to inject the meta tag
40
	// We'll insert it after og:description if it exists, or before twitter:card
41
	const ogDescriptionMatch = content.match(
42
		/<meta property="og:description"[^>]*>/,
43
	);
44
	const twitterCardMatch = content.match(/<meta name="twitter:card"[^>]*>/);
45
46
	let insertPosition: number;
47
	if (ogDescriptionMatch && ogDescriptionMatch.index !== undefined) {
48
		insertPosition = ogDescriptionMatch.index + ogDescriptionMatch[0].length;
49
	} else if (twitterCardMatch && twitterCardMatch.index !== undefined) {
50
		insertPosition = twitterCardMatch.index;
51
	} else {
52
		// Fallback: insert before </head>
53
		const headCloseMatch = content.indexOf("</head>");
54
		if (headCloseMatch === -1) {
55
			console.log(`⚠️  Warning: Could not find insertion point in ${filePath}`);
56
			return;
57
		}
58
		insertPosition = headCloseMatch;
59
	}
60
61
	// Inject the og:image and twitter:image meta tags
62
	const ogImageTag = `<meta property="og:image" content="${ogImageUrl}"/>`;
63
	const twitterImageTag = `<meta name="twitter:image" content="${ogImageUrl}"/>`;
64
	const newContent =
65
		content.slice(0, insertPosition) +
66
		ogImageTag +
67
		twitterImageTag +
68
		content.slice(insertPosition);
69
70
	// Write the modified content back to the file
71
	await Bun.write(filePath, newContent);
72
	console.log(`✅ Injected og:image tags into ${filePath}`);
73
}
74
75
// Main execution
76
async function main() {
77
	console.log("🔍 Finding HTML files in dist directory...");
78
	const htmlFiles = findHtmlFiles(distDir);
79
	console.log(`📄 Found ${htmlFiles.length} HTML files`);
80
81
	for (const file of htmlFiles) {
82
		await injectOgImageTags(file);
83
	}
84
85
	console.log("\n✨ Done! All HTML files have been processed.");
86
}
87
88
main();