diff --git a/infra/website/src/layouts/BaseLayout.astro b/infra/website/src/layouts/BaseLayout.astro index d73c7b0ebde..05d940005ba 100644 --- a/infra/website/src/layouts/BaseLayout.astro +++ b/infra/website/src/layouts/BaseLayout.astro @@ -4,9 +4,17 @@ import '../styles/global.css'; interface Props { title: string; description?: string; + socialImage?: string; + ogUrl?: string; } -const { title, description = "Feast is an end-to-end open source feature store for machine learning. It allows teams to define, manage, discover, and serve features." } = Astro.props; +const defaultSocialImage = "https://feast.dev/wp-content/uploads/2023/01/feast-og@2x.png"; +const { + title, + description = "Feast is an end-to-end open source feature store for machine learning. It allows teams to define, manage, discover, and serve features.", + socialImage = defaultSocialImage, + ogUrl = "https://feast.dev/", +} = Astro.props; --- @@ -25,16 +33,16 @@ const { title, description = "Feast is an end-to-end open source feature store f - + - + - + @@ -51,4 +59,4 @@ const { title, description = "Feast is an end-to-end open source feature store f - \ No newline at end of file + diff --git a/infra/website/src/pages/blog/[slug].astro b/infra/website/src/pages/blog/[slug].astro index 7d6a780a14c..90e8572d0b2 100644 --- a/infra/website/src/pages/blog/[slug].astro +++ b/infra/website/src/pages/blog/[slug].astro @@ -1,6 +1,25 @@ --- import BaseLayout from '../../layouts/BaseLayout.astro'; import Navigation from '../../components/Navigation.astro'; +import { readFileSync } from 'node:fs'; + +const SITE_URL = 'https://feast.dev'; + +function toAbsoluteUrl(path: string): string { + if (/^https?:\/\//i.test(path)) { + return path; + } + return new URL(path, SITE_URL).toString(); +} + +function extractHeroImage(markdown: string): string | undefined { + const heroContainerMatch = markdown.match(/]*class=["'][^"']*\bhero-image\b[^"']*["'][^>]*>([\s\S]*?)<\/div>/i); + if (!heroContainerMatch?.[1]) { + return undefined; + } + const imageMatch = heroContainerMatch[1].match(/]*\bsrc=["']([^"']+)["'][^>]*>/i); + return imageMatch?.[1]; +} export async function getStaticPaths() { const posts = await Astro.glob('../../../docs/blog/*.md'); @@ -17,9 +36,13 @@ export async function getStaticPaths() { const { post } = Astro.props; const { title, description, date, authors = [] } = post.frontmatter; +const blogUrl = `${SITE_URL}/blog/${Astro.params.slug}/`; +const frontmatterImage = post.frontmatter.hero_image || post.frontmatter.heroImage || post.frontmatter.image; +const heroImage = frontmatterImage || extractHeroImage(readFileSync(post.file, 'utf-8')); +const socialImage = heroImage ? toAbsoluteUrl(heroImage) : undefined; --- - +
@@ -316,4 +339,4 @@ const { title, description, date, authors = [] } = post.frontmatter; font-size: 18px; } } - \ No newline at end of file +