Repository navigation
fix(seo): render SVG feature images to PNG for og:image, add social preview tags - #768
Merged
Merged
Conversation
Deploying ddev-com-front-end with
|
| Latest commit: |
606fe2b
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5c6452ee.ddev-com-front-end.pages.dev |
| Branch Preview URL: | https://20261026-stasadev-og-png.ddev-com-front-end.pages.dev |
## Short Summary (TL;DR) Social networks don't show SVG in `og:image`, so blog posts with an SVG feature image had no preview image when shared. The build now renders a PNG copy of each one and uses it for `og:image`. ## How This PR Solves The Issue A new endpoint, `src/pages/img/blog/[...path].png.js`, uses `sharp` to render each SVG feature image under `/img/blog/` to a 1200px wide PNG at the same path, so `banner.svg` gets `banner.png` next to it in `dist/` and no image files are committed. The blog post page uses that PNG for `og:image` and the JSON-LD `image`, while PNG and JPG feature images stay as they were. The build fails if a PNG with the same name already exists in `public/`, because it would clash with the generated file. ## Manual Testing Instructions - Open https://20261026-stasadev-og-png.ddev-com-front-end.pages.dev/img/blog/2026/09/banner-ddev-v1-25-4.png and check that it shows the "DDEV v1.25.4 Release" text, not only the logo. SVG text needs fonts in the Cloudflare build image, which is not verified yet. - View the source of https://20261026-stasadev-og-png.ddev-com-front-end.pages.dev/blog/release-v1-25-4/ and check that `og:image` ends in `banner-ddev-v1-25-4.png`, while https://ddev.com/blog/release-v1-25-4/ still has the `.svg`. - Paste the preview post URL into the LinkedIn Post Inspector or the Facebook Sharing Debugger and check that the image appears. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew builds ## Short Summary (TL;DR) On Cloudflare preview builds, `og:image` now uses the preview deployment's own URL instead of `https://ddev.com`, so share checkers such as opengraph.to can load images that only exist on the branch. ## How This PR Solves The Issue `og:image` was always built from `site` in `astro.config.mjs`, so a preview advertised its images on production, where a new image returns 404 until the branch is merged. `Layout.astro` now uses `CF_PAGES_URL` for `og:image` when Cloudflare Pages builds a branch other than `main`. Canonical URLs and JSON-LD still point at `https://ddev.com`, and fork previews, which are built in GitHub Actions without these variables, keep using `https://ddev.com` as before. ## Manual Testing Instructions - View the source of https://20261026-stasadev-og-png.ddev-com-front-end.pages.dev/blog/release-v1-25-4/ and check that `og:image` points at a `*.ddev-com-front-end.pages.dev` URL that loads, while `<link rel="canonical">` is still `https://ddev.com/blog/release-v1-25-4/`. - Run https://www.opengraph.to/u/20261026-stasadev-og-png.ddev-com-front-end.pages.dev/blog/release-v1-25-4 and check that the image loads. - Check that https://ddev.com/blog/release-v1-25-4/ is unaffected after merge, with `og:image` on `https://ddev.com`. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ew builds ## Short Summary (TL;DR) Fork previews are built in GitHub Actions, which doesn't set `CF_PAGES_URL`, so their `og:image` still pointed at `https://ddev.com`. The fork build now passes its `pr-<number>` preview URL as `PREVIEW_URL`, and `Layout.astro` uses it for `og:image`. ## Manual Testing Instructions - On the next fork PR, view the source of a page on `https://pr-<number>.ddev-com-fork-previews.pages.dev/` and check that `og:image` points at that host. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## Short Summary (TL;DR) opengraph.to flagged missing `twitter:card` and `og:image` dimensions, so X showed a small thumbnail card and Facebook or LinkedIn could show no image on a link's first share. Every page now sets `twitter:card` to `summary_large_image`, `og:locale` to `en_US`, and `og:image:width` and `og:image:height`. ## How This PR Solves The Issue The dimensions come from the Astro asset metadata that `src/lib/images.ts` already loads for raster images under `public/img`, or, for a PNG rendered from an SVG feature image, from the render itself. That render moved into `src/lib/images.ts` and is cached, so the endpoint and the page reporting its size share one result. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## Short Summary (TL;DR) The `BlogPosting` JSON-LD `image` was a relative path such as `/img/og-default.png`, while Google's structured data documentation asks for absolute URLs. It now resolves against `https://ddev.com`, like the canonical URL. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stasadev
force-pushed
the
20261026_stasadev_og_png
branch
from
October 26, 2026 15:02
1f4b3b5 to
606fe2b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Short Summary (TL;DR)
Social networks don't show SVG in
og:image, so blog posts with an SVG feature image had no preview image when shared. The build now renders a PNG copy of each one, every page gets thetwitter:card,og:locale, andog:imagedimension tags that https://www.opengraph.to/ reported missing, and preview builds pointog:imageat their own deployment, so this can be checked before merging.How This PR Solves The Issue
A new endpoint,
src/pages/img/blog/[...path].png.js, usessharpto render each SVG feature image under/img/blog/to a 1200px wide PNG at the same path, sobanner.svggetsbanner.pngnext to it indist/and no image files are committed. The blog post page uses that PNG forog:imageand the JSON-LDimage, while PNG and JPG feature images stay as they were. The build fails if a PNG with the same name already exists inpublic/, because it would clash with the generated file.The
BlogPostingJSON-LDimageis now an absolute URL onhttps://ddev.com, as Google's structured data documentation asks.twitter:cardissummary_large_image, so X shows the large image instead of a small thumbnail.og:image:widthandog:image:heightlet Facebook and LinkedIn show the image on a link's first share, and they come from the Astro asset metadata for raster images or from the PNG render for SVGs.og:imageused to be built fromsiteinastro.config.mjson every build, so a preview pointed at images onhttps://ddev.com, where a new image returns 404 until merge. Cloudflare preview builds now useCF_PAGES_URLinstead, and fork preview builds, which run in GitHub Actions, get theirpr-<number>URL asPREVIEW_URL. Canonical URLs stay onhttps://ddev.com.Manual Testing Instructions
I tested the previews with https://www.opengraph.to/, which loads the page from outside and reports the tags it finds and whether the image loads.
twitter:cardor image dimensions.og:imagepoints at a*.ddev-com-front-end.pages.devPNG withog:image:width1200 andog:image:height800, while<link rel="canonical">is stillhttps://ddev.com/blog/release-v1-25-4/.upsun-ddev.png.Release/Deployment Notes
After merge, production
og:imagestays onhttps://ddev.com. Social networks may keep a cached preview for posts that were already shared until it is refreshed in their debugger tools.🤖 Developed with assistance from Claude Code