Custom OG image renderer with pg_orbit branding
Replace generic blackAndWhite preset with custom renderer using site colors (#0a0e17 dark background, #f59e0b amber accents), decorative orbital rings watermark, branded footer with pg_orbit name and site URL. Inter font in 400/700 weights.
This commit is contained in:
parent
86a2e386b7
commit
27a6e7106f
@ -5,7 +5,8 @@ import remarkMath from "remark-math";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import mermaid from "astro-mermaid";
|
||||
import icon from "astro-icon";
|
||||
import opengraphImages, { presets } from "astro-opengraph-images";
|
||||
import opengraphImages from "astro-opengraph-images";
|
||||
import { pgOrbitOgImage } from "./src/og-renderer.js";
|
||||
import * as fs from "fs";
|
||||
|
||||
export default defineConfig({
|
||||
@ -135,7 +136,7 @@ export default defineConfig({
|
||||
},
|
||||
],
|
||||
},
|
||||
render: presets.blackAndWhite,
|
||||
render: pgOrbitOgImage,
|
||||
}),
|
||||
],
|
||||
|
||||
|
||||
183
docs/src/og-renderer.tsx
Normal file
183
docs/src/og-renderer.tsx
Normal file
@ -0,0 +1,183 @@
|
||||
import React from "react";
|
||||
import type { RenderFunctionInput } from "astro-opengraph-images";
|
||||
|
||||
export async function pgOrbitOgImage({
|
||||
title,
|
||||
description,
|
||||
}: RenderFunctionInput): Promise<React.ReactNode> {
|
||||
return Promise.resolve(
|
||||
<div
|
||||
style={{
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
backgroundColor: "#0a0e17",
|
||||
fontFamily: "Inter, system-ui, sans-serif",
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{/* Top accent bar */}
|
||||
<div
|
||||
style={{
|
||||
height: "4px",
|
||||
width: "100%",
|
||||
background: "linear-gradient(to right, #f59e0b, #fbbf24, #f59e0b)",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Decorative orbital rings (top-right) */}
|
||||
<svg
|
||||
width="320"
|
||||
height="320"
|
||||
viewBox="0 0 320 320"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-60px",
|
||||
right: "-40px",
|
||||
opacity: 0.08,
|
||||
}}
|
||||
>
|
||||
<ellipse
|
||||
cx="160"
|
||||
cy="160"
|
||||
rx="140"
|
||||
ry="60"
|
||||
stroke="#f59e0b"
|
||||
stroke-width="2"
|
||||
fill="none"
|
||||
transform="rotate(-20 160 160)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="160"
|
||||
cy="160"
|
||||
rx="120"
|
||||
ry="45"
|
||||
stroke="#fbbf24"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
transform="rotate(35 160 160)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="160"
|
||||
cy="160"
|
||||
rx="90"
|
||||
ry="35"
|
||||
stroke="#f59e0b"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
transform="rotate(-5 160 160)"
|
||||
/>
|
||||
<circle cx="160" cy="160" r="8" fill="#f59e0b" />
|
||||
</svg>
|
||||
|
||||
{/* Content area */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
flexGrow: 1,
|
||||
padding: "48px 64px",
|
||||
}}
|
||||
>
|
||||
{/* Title + description */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
marginTop: "32px",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 56,
|
||||
fontWeight: 700,
|
||||
color: "#e2e8f0",
|
||||
lineHeight: 1.15,
|
||||
maxWidth: "900px",
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
{description && (
|
||||
<div
|
||||
style={{
|
||||
fontSize: 28,
|
||||
color: "#8896a8",
|
||||
marginTop: "20px",
|
||||
lineHeight: 1.4,
|
||||
maxWidth: "800px",
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "12px",
|
||||
}}
|
||||
>
|
||||
{/* Amber dot */}
|
||||
<div
|
||||
style={{
|
||||
width: "12px",
|
||||
height: "12px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#f59e0b",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 24,
|
||||
fontWeight: 700,
|
||||
color: "#e2e8f0",
|
||||
}}
|
||||
>
|
||||
pg_orbit
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 20,
|
||||
color: "#556677",
|
||||
marginLeft: "4px",
|
||||
}}
|
||||
>
|
||||
Celestial mechanics for PostgreSQL
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 18,
|
||||
color: "#556677",
|
||||
}}
|
||||
>
|
||||
pg-orbit.warehack.ing
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom accent bar */}
|
||||
<div
|
||||
style={{
|
||||
height: "4px",
|
||||
width: "100%",
|
||||
background: "linear-gradient(to right, #f59e0b, #fbbf24, #f59e0b)",
|
||||
}}
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user