From 21b493e1a9813448547fc4c5a41f78f2ef3fe7fb Mon Sep 17 00:00:00 2001 From: Joey Chen <142381267+JoeyC-Dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:34:37 +0800 Subject: [PATCH 1/4] feat: add OpenGraph image support --- src/layouts/Layout.astro | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index c18052209c..cf0c2c82fb 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -30,6 +30,18 @@ interface Props { let { title, banner, description, lang, setOGTypeArticle } = Astro.props; +const currentPath = Astro.url.pathname; + +let ogImage: string | undefined = undefined; + +if (banner && typeof banner === 'string' && banner.trim() !== '') { + if (banner.startsWith('http://') || banner.startsWith('https://')) { + ogImage = banner; + } else { + ogImage = new URL(banner, Astro.site || Astro.url.origin).href; + } +} + // apply a class to the body element to decide the height of the banner, only used for initial page load // Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change // so use Swup hooks instead to change the height immediately when a link is clicked @@ -93,11 +105,13 @@ const bannerOffset = ) : ( )} + {ogImage && } + {ogImage && } @@ -564,4 +578,4 @@ if (window.swup) { } else { document.addEventListener("swup:enable", setup) } - + \ No newline at end of file From 29300f3a1e460930b5f9d7286bfb8ed9d11cd956 Mon Sep 17 00:00:00 2001 From: Joey Chen <142381267+JoeyC-Dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:54:40 +0800 Subject: [PATCH 2/4] fix code based on github action quality check --- src/layouts/Layout.astro | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index cf0c2c82fb..854793ad8e 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -30,9 +30,7 @@ interface Props { let { title, banner, description, lang, setOGTypeArticle } = Astro.props; -const currentPath = Astro.url.pathname; - -let ogImage: string | undefined = undefined; +let ogImage: string; if (banner && typeof banner === 'string' && banner.trim() !== '') { if (banner.startsWith('http://') || banner.startsWith('https://')) { @@ -578,4 +576,4 @@ if (window.swup) { } else { document.addEventListener("swup:enable", setup) } - \ No newline at end of file + From 7c1ba61eb2e9732b8ddf4225e14e43897dddfd34 Mon Sep 17 00:00:00 2001 From: Joey Chen <142381267+JoeyC-Dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 19:58:48 +0800 Subject: [PATCH 3/4] feat: add OG tags, published/modified time, canonical URL --- src/layouts/Layout.astro | 45 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 854793ad8e..13a77ddf35 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -19,6 +19,7 @@ import { defaultFavicons } from "../constants/icon"; import type { Favicon } from "../types/config"; import { pathsEqual, url } from "../utils/url-utils"; import "katex/dist/katex.css"; +import { getCollection } from "astro:content"; interface Props { title?: string; @@ -40,6 +41,33 @@ if (banner && typeof banner === 'string' && banner.trim() !== '') { } } +const slug = Astro.url.pathname.split('/').filter(Boolean).pop(); +let pageData = {}; + +try { + const allEntries = await getCollection("posts"); + const entry = allEntries.find(e => e.slug === slug); + if (entry) pageData = entry.data; +} catch (e) { + // No data, slient fail +} + +const formatDate = (date) => { + if (!date) return null; + if (date instanceof Date) { + return date.toISOString().split('T')[0]; + } + if (typeof date === 'string') { + return date.split('T')[0]; + } + return null; +}; + +const publishedDate = formatDate(pageData.published); +const updatedDate = formatDate(pageData.updated); + +const tags = pageData.tags || []; + // apply a class to the body element to decide the height of the banner, only used for initial page load // Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change // so use Swup hooks instead to change the height immediately when a link is clicked @@ -91,18 +119,27 @@ const bannerOffset = {pageTitle} + + {setOGTypeArticle ? ( - - ) : ( - - )} + <> + + {tags.map((tag) => ( + + ))} + {publishedDate && } + {updatedDate && } + + ) : ( + + )} {ogImage && } From c31ce80798908f161d0836598eece2d395df5461 Mon Sep 17 00:00:00 2001 From: Joey Chen <142381267+JoeyC-Dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:03:58 +0800 Subject: [PATCH 4/4] fix astro check error --- src/layouts/Layout.astro | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 13a77ddf35..865e87d390 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -31,7 +31,7 @@ interface Props { let { title, banner, description, lang, setOGTypeArticle } = Astro.props; -let ogImage: string; +let ogImage: string | undefined = undefined; if (banner && typeof banner === 'string' && banner.trim() !== '') { if (banner.startsWith('http://') || banner.startsWith('https://')) { @@ -42,17 +42,24 @@ if (banner && typeof banner === 'string' && banner.trim() !== '') { } const slug = Astro.url.pathname.split('/').filter(Boolean).pop(); -let pageData = {}; + +interface PageData { + published?: Date | string; + updated?: Date | string; + tags?: string[]; +} + +let pageData: PageData = {}; try { const allEntries = await getCollection("posts"); const entry = allEntries.find(e => e.slug === slug); - if (entry) pageData = entry.data; + if (entry) pageData = entry.data as PageData; } catch (e) { - // No data, slient fail + // No data, silent fail } -const formatDate = (date) => { +const formatDate = (date: Date | string | undefined): string | null => { if (!date) return null; if (date instanceof Date) { return date.toISOString().split('T')[0]; @@ -66,7 +73,7 @@ const formatDate = (date) => { const publishedDate = formatDate(pageData.published); const updatedDate = formatDate(pageData.updated); -const tags = pageData.tags || []; +const tags: string[] = pageData.tags || []; // apply a class to the body element to decide the height of the banner, only used for initial page load // Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change @@ -131,7 +138,7 @@ const bannerOffset = {setOGTypeArticle ? ( <> - {tags.map((tag) => ( + {tags.map((tag: string) => ( ))} {publishedDate && }