diff --git a/packages/landing/public/blog/obsidian-plugin-is-live/images/cover.png b/packages/landing/public/blog/obsidian-plugin-is-live/images/cover.png new file mode 100644 index 0000000..ad5854a Binary files /dev/null and b/packages/landing/public/blog/obsidian-plugin-is-live/images/cover.png differ diff --git a/packages/landing/public/blog/obsidian-plugin-is-live/images/flow.png b/packages/landing/public/blog/obsidian-plugin-is-live/images/flow.png new file mode 100644 index 0000000..5dfc89a Binary files /dev/null and b/packages/landing/public/blog/obsidian-plugin-is-live/images/flow.png differ diff --git a/packages/landing/src/app/blog/[slug]/page.tsx b/packages/landing/src/app/blog/[slug]/page.tsx index a9d1b2e..6c90498 100644 --- a/packages/landing/src/app/blog/[slug]/page.tsx +++ b/packages/landing/src/app/blog/[slug]/page.tsx @@ -65,12 +65,33 @@ export default async function BlogPostPage({ params }: { params: Promise ...(post.ogImageUrl ? { image: `${SITE_URL}${post.ogImageUrl}` } : {}), }; + // Emit FAQPage structured data when a post declares an faq array, so the Q&A + // is eligible for rich results. Answers must match the visible FAQ text. + const faqJsonLd = + post.faq && post.faq.length > 0 + ? { + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: post.faq.map((item) => ({ + '@type': 'Question', + name: item.question, + acceptedAnswer: { '@type': 'Answer', text: item.answer }, + })), + } + : null; + return (