mirror of
https://github.com/zoriya/v10.git
synced 2026-08-05 05:37:21 +00:00
feat(site): add default OG image for social sharing (#1295)
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Generates the default OG image: Video.js mono logo in manila on a dark background.
|
||||
*
|
||||
* Usage: node scripts/generate-og-default.mjs
|
||||
* Output: public/og-default.png (1200×630)
|
||||
*/
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const BACKGROUND = '#1e1d1d'; // faded-black (dark mode bg)
|
||||
const LOGO_FILL = '#f3e7d2'; // manila-light
|
||||
const WIDTH = 1200;
|
||||
const HEIGHT = 630;
|
||||
|
||||
// Read the mono logo SVG and replace currentColor with manila
|
||||
const logoSvg = readFileSync(resolve(__dirname, '../src/assets/logos/videojs-mono.svg'), 'utf-8');
|
||||
|
||||
// The logo viewBox is 0 0 381 68 → aspect ratio ~5.6:1
|
||||
const logoNativeW = 381;
|
||||
const logoNativeH = 68;
|
||||
const logoAspect = logoNativeW / logoNativeH;
|
||||
|
||||
// ~80% of image width
|
||||
const logoW = Math.round(WIDTH * 0.8);
|
||||
const logoH = Math.round(logoW / logoAspect);
|
||||
|
||||
// Prepare the logo SVG at the target size with manila fill
|
||||
const coloredLogo = logoSvg
|
||||
.replace(/currentColor/g, LOGO_FILL)
|
||||
.replace(/<svg /, `<svg width="${logoW}" height="${logoH}" `);
|
||||
|
||||
// Optical centering: nudge the logo 10 px left of mathematical centre.
|
||||
const nudgeLeft = 10;
|
||||
|
||||
const centreLeft = Math.round((WIDTH - logoW) / 2);
|
||||
const centreTop = Math.round((HEIGHT - logoH) / 2);
|
||||
|
||||
const image = sharp({
|
||||
create: {
|
||||
width: WIDTH,
|
||||
height: HEIGHT,
|
||||
channels: 4,
|
||||
background: BACKGROUND,
|
||||
},
|
||||
})
|
||||
.composite([
|
||||
{
|
||||
input: Buffer.from(coloredLogo),
|
||||
left: centreLeft - nudgeLeft,
|
||||
top: centreTop,
|
||||
},
|
||||
])
|
||||
.png();
|
||||
|
||||
const outputPath = resolve(__dirname, '../public/og-default.png');
|
||||
await image.toFile(outputPath);
|
||||
console.log(`Generated ${outputPath} (${WIDTH}×${HEIGHT})`);
|
||||
@@ -31,6 +31,7 @@ function resolveImageUrl(img: ImageMetadata | string): string {
|
||||
return new URL(img.src, Astro.url).toString();
|
||||
}
|
||||
|
||||
const defaultOgImage = new URL('/og-default.png', Astro.site).toString();
|
||||
const resolvedTwitterImage = twitterImage ?? image;
|
||||
|
||||
const seoSuffix = suffix ?? SEO_SUFFIX;
|
||||
@@ -113,7 +114,10 @@ const fullTitle =
|
||||
/>
|
||||
<meta property="og:title" content={fullTitle} />
|
||||
<meta property="og:description" content={description} />
|
||||
{image && <meta property="og:image" content={resolveImageUrl(image)} />}
|
||||
<meta
|
||||
property="og:image"
|
||||
content={image ? resolveImageUrl(image) : defaultOgImage}
|
||||
/>
|
||||
|
||||
{/* Twitter */}
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
@@ -123,14 +127,12 @@ const fullTitle =
|
||||
/>
|
||||
<meta property="twitter:title" content={fullTitle} />
|
||||
<meta property="twitter:description" content={description} />
|
||||
{
|
||||
resolvedTwitterImage && (
|
||||
<meta
|
||||
property="twitter:image"
|
||||
content={resolveImageUrl(resolvedTwitterImage)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<meta
|
||||
property="twitter:image"
|
||||
content={resolvedTwitterImage
|
||||
? resolveImageUrl(resolvedTwitterImage)
|
||||
: defaultOgImage}
|
||||
/>
|
||||
|
||||
{/* Whatever else */}
|
||||
<slot name="head" />
|
||||
|
||||
Reference in New Issue
Block a user