Generate per-article OG images for blog posts#71
Conversation
Every blog article shared the default OG image because computeOgPath() mapped /blog/* to /og/default.png and the blog page layout never set an explicit metaImage. Shares from /blog/<slug> on social platforms all looked identical. - Add src/pages/og/blog/[slug].png.ts that iterates the blog content collection and renders one PNG per article via pageTemplate, using the article title and locale-formatted date as copy. - Wire src/pages/blog/[...slug].astro to pass metaImage pointing at that endpoint. - Add a dedicated /og/pages/blog.png for the blog index (was still falling through to default). - Update computeOgPath: /blog now returns the blog index OG image; /blog/<slug> articles pass an explicit metaImage from the page frontmatter so the fallback path is only used for unknown routes. Build regenerates 7 blog PNGs + 1 blog index PNG. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
|
Visit the preview URL for this PR (updated for commit 90b24e6): https://sunnytechwebsite--pr71-blog-og-images-ohnus1bz.web.app (expires Fri, 01 May 2026 07:03:44 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: b96ac7ab85879442bb94dc448b41aeca0f34d16c |
There was a problem hiding this comment.
Pull request overview
Generates unique Open Graph (OG) images for individual blog articles and ensures the blog index uses a dedicated OG image, so social shares no longer all show the default card.
Changes:
- Add a new OG image endpoint that prerenders one PNG per blog post (
/og/blog/<slug>.png). - Set blog article pages to pass an explicit
metaImagepointing to their per-article OG PNG. - Add a dedicated OG image for the
/blogindex and route/blogto it in OG path computation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/pages/og/pages/[page].png.ts | Adds a blog page spec so /og/pages/blog.png can be generated. |
| src/pages/og/blog/[slug].png.ts | New endpoint to generate per-article OG PNGs from the blog content collection. |
| src/pages/blog/[...slug].astro | Passes per-article metaImage to the layout for correct OG tags. |
| src/og/ogImage.ts | Routes /blog to the blog index OG image and keeps /blog/* fallback behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const GET: APIRoute = async ({ params, props }) => { | ||
| const cacheKey = `blog/${params.slug}.png` | ||
| const cached = await readOgCache(cacheKey) | ||
| if (cached) return pngResponse(cached) |
There was a problem hiding this comment.
The OG cache key is only based on the slug (blog/<slug>.png). In CI, .og-cache is restored across builds, and reads are enabled, so updating a post’s title/date/content won’t invalidate the cached PNG and the OG image can become stale in production.
Consider versioning the cache key with some representation of the post inputs (e.g., hash of props.title + props.date, or a content digest passed from getStaticPaths) so content edits force a re-render while keeping the public URL stable.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Done in 90b24e6. The cache key now includes an 8-character SHA-256 hash of props.title + props.date, so any edit to a post's title or date produces a new key and forces a re-render, while the public URL (/og/blog/<slug>.png) remains unchanged.
Agent-Logs-Url: https://github.com/Sunny-Tech/SunnyTechWebsite/sessions/80f49c89-1d22-4189-a468-4fc3245403c1 Co-authored-by: HugoGresse <662377+HugoGresse@users.noreply.github.com>
Summary
Every blog article shared the default OG image because `computeOgPath()` mapped `/blog/*` → `/og/default.png` and the blog layout never set an explicit `metaImage`. Shares from every `/blog/` URL looked identical on Twitter/LinkedIn/Slack.
Changes
Verified locally
Test plan
🤖 Generated with Claude Code