From a397bc80d4c15c4ee57b071118e6c521e4fee1ca Mon Sep 17 00:00:00 2001 From: Adam Miedema Date: Fri, 13 Feb 2026 13:42:48 -0700 Subject: [PATCH] improve image choice --- app.config.ts | 2 +- pages/[...slug].vue | 58 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/app.config.ts b/app.config.ts index b1ddb36..3eb530a 100644 --- a/app.config.ts +++ b/app.config.ts @@ -4,7 +4,7 @@ export default defineAppConfig({ name: "Msty Studio Docs", description: "Get started with guides and resources to maximize your conversational AI experience with Msty Studio.", - ogImage: "https://docs.msty.studio/images/quick-start.png", + ogImage: "https://docs.msty.studio/images/welcome-to-msty.png", }, theme: { customizable: false, diff --git a/pages/[...slug].vue b/pages/[...slug].vue index 625e717..ee018cc 100644 --- a/pages/[...slug].vue +++ b/pages/[...slug].vue @@ -70,15 +70,67 @@ const { page } = useContent(); const config = useConfig(); const appConfig = useAppConfig(); -const fallbackSocialImage = "https://docs.msty.studio/images/quick-start.png"; +const siteBaseUrl = "https://docs.msty.studio"; +const fallbackSocialImage = `${siteBaseUrl}/images/welcome-to-msty.png`; + +function toAbsoluteImageUrl(src: string): string { + if (/^https?:\/\//i.test(src)) { + return src; + } + if (src.startsWith("//")) { + return `https:${src}`; + } + if (src.startsWith("/")) { + return `${siteBaseUrl}${src}`; + } + return `${siteBaseUrl}/${src}`; +} + +function findFirstImageSrc(node: unknown): string | null { + if (!node || typeof node !== "object") { + return null; + } + + const n = node as { + type?: string; + tag?: string; + props?: Record; + children?: unknown[]; + }; + + if (n.type === "element" && n.tag === "img") { + const src = n.props?.src; + if (typeof src === "string" && src.trim().length > 0) { + return src.trim(); + } + } + + if (!Array.isArray(n.children)) { + return null; + } + + for (const child of n.children) { + const found = findFirstImageSrc(child); + if (found) { + return found; + } + } + + return null; +} + +const socialImage = computed(() => { + const firstImageSrc = findFirstImageSrc(page.value?.body); + return firstImageSrc ? toAbsoluteImageUrl(firstImageSrc) : fallbackSocialImage; +}); useSeoMeta({ title: `${page.value?.title ?? "404"} - ${config.value.site.name}`, ogTitle: page.value?.title, description: page.value?.description, ogDescription: page.value?.description, - ogImage: fallbackSocialImage, + ogImage: () => socialImage.value, twitterCard: "summary_large_image", - twitterImage: fallbackSocialImage, + twitterImage: () => socialImage.value, });