@@ -3,6 +3,31 @@ import fs from "fs";
33import matter from "gray-matter" ;
44import path from "path" ;
55
6+ /**
7+ * Verifies if an image exists and has appropriate dimensions for social media
8+ * @param {string } imagePath - Path to the image relative to static directory
9+ * @returns {object } - Object containing verified image path and dimensions
10+ */
11+ function verifyImage ( imagePath ) {
12+ const defaultImage = "/assets/media/website_screenshot.png" ;
13+ const localImagePath = path . join ( process . cwd ( ) , "static" , imagePath ) ;
14+
15+ if ( ! fs . existsSync ( localImagePath ) ) {
16+ console . warn ( `Warning: Image not found at ${ imagePath } . Using default.` ) ;
17+ return {
18+ path : defaultImage ,
19+ width : 1200 ,
20+ height : 630
21+ } ;
22+ }
23+
24+ return {
25+ path : imagePath ,
26+ width : 1200 , // Default OG image width
27+ height : 630 // Default OG image height
28+ } ;
29+ }
30+
631/**
732 * Extracts metadata from a markdown file
833 * @param {string } slug - The slug/identifier for the blog post
@@ -167,27 +192,15 @@ export function injectMetaTags(html, url) {
167192 ? `/assets/og/${ slug } .png`
168193 : "/assets/media/website_screenshot.png" ;
169194
170- // Verify image exists, fall back to default if not
171- let finalImagePath = customOgImagePath ;
172- const localImagePath = path . join (
173- process . cwd ( ) ,
174- "static" ,
175- customOgImagePath
176- ) ;
177-
178- if ( ! fs . existsSync ( localImagePath ) ) {
179- console . warn ( `Warning: OG image not found for ${ slug } . Using default.` ) ;
180- finalImagePath = "/assets/media/website_screenshot.png" ;
181- }
195+ // Verify image exists, get dimensions, fall back to default if needed
196+ const verifiedImage = verifyImage ( customOgImagePath ) ;
197+ const finalImagePath = verifiedImage . path ;
182198
183199 // Make sure the image URL is absolute and doesn't have any special characters
184- const absoluteImageUrl = `${ siteUrl } ${ finalImagePath . replace (
185- / \s / g,
186- "%20"
187- ) } `;
200+ const absoluteImageUrl = new URL ( finalImagePath , siteUrl ) . toString ( ) ;
188201
189202 // Generate absolute URL for the post - ensure no trailing slash
190- const absoluteUrl = ` ${ siteUrl } /blog/${ slug } `;
203+ const absoluteUrl = new URL ( ` /blog/${ slug } `, siteUrl ) . toString ( ) ;
191204
192205 // Create the meta tag string - with escaping for special characters
193206 // Enforce Twitter character limits
226239<meta name="twitter:title" content="${ safeTitle } " />
227240<meta name="twitter:description" content="${ safeDescription } " />
228241<meta name="twitter:image" content="${ absoluteImageUrl } " />
242+ <meta property="twitter:image" content="${ absoluteImageUrl } " />
229243<meta name="twitter:image:alt" content="${ safeTitle } " />
230244<meta name="twitter:domain" content="${ siteUrl . replace ( / ^ h t t p s ? : \/ \/ / , "" ) } " />
231245
238252<meta property="og:image" content="${ absoluteImageUrl } " />
239253<meta property="og:image:secure_url" content="${ absoluteImageUrl } " />
240254<meta property="og:image:type" content="image/png" />
241- <meta property="og:image:width" content="1200 " />
242- <meta property="og:image:height" content="630 " />
255+ <meta property="og:image:width" content="${ verifiedImage . width } " />
256+ <meta property="og:image:height" content="${ verifiedImage . height } " />
243257<meta property="og:locale" content="en_US" />
244258${
245259 formattedDate
0 commit comments