feat: add basic satori og image generation

This commit is contained in:
Ben Schlegel 2023-09-19 19:41:42 +02:00
parent 6a2e0b3ad3
commit 715446272a
No known key found for this signature in database
GPG Key ID: 8BDB8891C1575E22
2 changed files with 59 additions and 1 deletions

View File

@ -77,6 +77,7 @@
"remark-rehype": "^10.1.0",
"remark-smartypants": "^2.0.0",
"rimraf": "^5.0.1",
"satori": "^0.10.6",
"serve-handler": "^6.1.5",
"source-map-support": "^0.5.21",
"to-vfile": "^7.2.4",

View File

@ -1,9 +1,65 @@
import { FullSlug, _stripSlashes, joinSegments, pathToRoot } from "../util/path"
import { JSResourceToScriptElement } from "../util/resources"
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import satori from "satori"
import * as fs from "fs"
const robotoData = await (
await fetch("https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Me5Q.ttf")
).arrayBuffer()
async function generateSvg(title: string, filePath: string) {
const svg = await satori(
<div
style={{
color: "black",
backgroundColor: "green",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 64,
}}
>
{title}
</div>,
{
width: 1200,
height: 675,
fonts: [
{
name: "Roboto",
// Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
data: robotoData,
weight: 400,
style: "normal",
},
],
},
)
fs.writeFileSync(`public/static/${filePath}.svg`, svg)
}
export default (() => {
function Head({ cfg, fileData, externalResources }: QuartzComponentProps) {
const dir = "public/static"
const slug = fileData.filePath
const filePath = slug?.replaceAll("/", "-")
const ogArr = slug?.split("/")
const ogTitle = fileData.frontmatter?.title ?? "Untitled"
// const title = fileData?.fron
// console.log("filePath: ", filePath)
// if (ogTitle && filePath) {
console.log("OG title: ", ogTitle)
generateSvg(ogTitle as string, filePath as string)
// }
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
}
const title = fileData.frontmatter?.title ?? "Untitled"
const description = fileData.description?.trim() ?? "No description provided"
const { css, js } = externalResources
@ -14,6 +70,7 @@ export default (() => {
const iconPath = joinSegments(baseDir, "static/icon.png")
const ogImagePath = `https://${cfg.baseUrl}/static/og-image.png`
const ogImagePathNew = `https://${cfg.baseUrl}/static/${filePath}.svg`
return (
<head>
@ -22,7 +79,7 @@ export default (() => {
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
{cfg.baseUrl && <meta property="og:image" content={ogImagePath} />}
{cfg.baseUrl && <meta property="og:image" content={ogImagePathNew} />}
<meta property="og:width" content="1200" />
<meta property="og:height" content="675" />
<link rel="icon" href={iconPath} />