From a465df835ca978dd2cd1d1ac7c75daf5a49f350a Mon Sep 17 00:00:00 2001 From: clover caruso Date: Tue, 23 Dec 2025 14:18:14 -0800 Subject: [PATCH] fix(q+a): issues gernerating question embed images this fixes multiple issues: - the font files were not avaialble - the user-agent detection was wrong - the opengraph object format changed these all happened with the move to sitegen and not testing things. i never noticed any of these bugs since i don't use discord much these days, but i really do like having this feature. now, puppeteer is set to open against localhost, which loads the exact page experience as normal. --- src/q+a/backend.ts | 3 +++ src/q+a/image.tsx | 7 ++++--- src/q+a/views/permalink.marko | 12 +++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/q+a/backend.ts b/src/q+a/backend.ts index e4d52cf0b13e6d652346964e526d43e47b926c16..441be17fbc227c9a9717e9ee51f521cd004c04e9 100644 --- a/src/q+a/backend.ts +++ b/src/q+a/backend.ts @@ -127,6 +127,9 @@ app.get("/q+a/:id", async (c, next) => { if (image) { return getQuestionImage(question, c.req.method === "HEAD"); } + if (c.req.header("User-Agent")?.includes("clover-qa-image")) { + return view.serve(c, "q+a/image-embed", { question }); + } return view.serve(c, "q+a/permalink", { question }); }); diff --git a/src/q+a/image.tsx b/src/q+a/image.tsx index 44a183183ba462b312d9e6fc0c80253857c1374e..89e630fb9ad42261e7cfa7f4c1c227f2422b2cd1 100644 --- a/src/q+a/image.tsx +++ b/src/q+a/image.tsx @@ -1,3 +1,4 @@ +const port = Number(process.env.PORT ?? 3000); const width = 768; const cacheImageDir = path.resolve(".clover/question_images"); @@ -11,8 +12,6 @@ const getBrowser = RefCountedExpirable( ); export async function renderQuestionImage(question: Question) { - const html = await view.renderToString("q+a/image-embed", { question }); - // this browser session will be reused if multiple images are generated // either at the same time or within a 5-minute time span. the dispose // symbol @@ -20,12 +19,14 @@ export async function renderQuestionImage(question: Question) { const b = sharedBrowser.value; const p = await b.newPage(); + await p.setUserAgent({ userAgent: "clover-qa-image" }); await p.setViewport({ width, height: 400 }); - await p.setContent(html); + await p.goto(`http://localhost:${port}/q+a/${question.id}`); try { await p.waitForNetworkIdle({ idleTime: 100, timeout: 500 }); } catch (e) {} const height = await p.evaluate(() => { + document.body.style.background = "#1a1b1c"; const e = document.querySelector("main")!; return e.getBoundingClientRect().height; }); diff --git a/src/q+a/views/permalink.marko b/src/q+a/views/permalink.marko index 2c8e53967eaed3c11be4864edccf30072eacf835..b9e2d3d602e239c3170547124181a437b15de461 100644 --- a/src/q+a/views/permalink.marko +++ b/src/q+a/views/permalink.marko @@ -4,14 +4,16 @@ export interface Input { } server export function meta({ context, question }) { - const isDiscord = context.get("user-agent") + console.log(context.req.header("user-agent")); + const isDiscord = context.req.header("user-agent") ?.toLowerCase() - .includes("discordbot"); + .includes("discord"); if (question.type === QuestionType.normal) { return { title: "question permalink", openGraph: { - images: [{ url: `https://paperclover.net/q+a/${question.id}.png` }], + title: isDiscord ? undefined : `question at ${formatQuestionTimestamp(question.date)}`, + image: `https://paperclover.net/q+a/${question.id}.png` }, twitter: { card: "summary_large_image" }, themeColor: isDiscord @@ -46,4 +48,8 @@ server export function meta({ context, question }) {
${JSON.stringify(question, null, 2)}
+view more questions + import { Question, QuestionType } from '@/q+a/models/Question.ts'; +import { transitionDate } from "@/q+a/tags/question.marko"; +import { formatQuestionTimestamp } from "@/q+a/format.ts"; -- 2.54.0