Skip to content

fix: serve static Open Graph images on Cloudflare - #30

Merged
radiumcoders merged 1 commit into
mainfrom
cursor/fix-og-image-d25d
Sep 13, 2026
Merged

radiumcoders merged 1 commit into
mainfrom
cursor/fix-og-image-d25d

Conversation

@radiumcoders

@radiumcoders radiumcoders commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Problem

Docs pages emit og:image / twitter:image as https://23rd.dev/og/docs/.../image.png. That URL was a next/og ImageResponse route. On Cloudflare Workers it dies immediately (500 Server failed to respond in a few ms). Slack, Discord, X, and iMessage therefore get no preview card.

The static app/opengraph-image.png already works. The broken route overrode it on every docs page.

next/og (Satori + yoga.wasm) is a known bad fit for this OpenNext/Cloudflare deploy — the same reason the earlier catch-all opengraph-image.tsx had to be moved off app/docs/[[...slug]].

Fix

  • Pre-render a 1200×630 PNG per docs page into public/og/docs/.../image.png (pnpm og:build)
  • Delete the runtime /og/docs/[...slug] route so Workers never load next/og
  • Keep the same metadata URLs — Cloudflare now serves real static assets
  • Point the root layout at the default card as well

pnpm build, pnpm preview, and pnpm cf:deploy all run og:build first so new docs pages get a card.

Verify

curl -sI http://localhost:3000/og/docs/image.png
# Content-Type: image/png

curl -s http://localhost:3000/docs | rg 'og:image'
# https://23rd.dev/og/docs/image.png
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features
    • Documentation pages now have branded, static Open Graph preview images for sharing.
    • Social sharing metadata now includes image dimensions, format, and preview images for documentation pages.
  • Improvements
    • Documentation preview images are generated automatically during builds and deployments, helping ensure previews stay synchronized with published content.
    • Open Graph image paths now follow a consistent format across documentation pages.

Docs pages pointed og:image at a next/og route that 500s on Workers.
Pre-render the cards into public/og so crawlers get real PNGs.

Co-authored-by: sharmaji582009 <sharmaji582009@gmail.com>
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 0dcdfe37-a7a6-42b1-a6f4-895856b893ad

📥 Commits

Reviewing files that changed from the base of the PR and between 8cfea50 and 75933b9.

⛔ Files ignored due to path filters (15)
  • public/og/docs/components/ascii-fluid/image.png is excluded by !**/*.png
  • public/og/docs/components/ascii-logo/image.png is excluded by !**/*.png
  • public/og/docs/components/dithered-404/image.png is excluded by !**/*.png
  • public/og/docs/components/folio/image.png is excluded by !**/*.png
  • public/og/docs/components/gooey-color-picker/image.png is excluded by !**/*.png
  • public/og/docs/components/live-orb/image.png is excluded by !**/*.png
  • public/og/docs/components/logo-burst/image.png is excluded by !**/*.png
  • public/og/docs/components/phosphor-score/image.png is excluded by !**/*.png
  • public/og/docs/components/radiant-lines/image.png is excluded by !**/*.png
  • public/og/docs/components/shader-fire/image.png is excluded by !**/*.png
  • public/og/docs/components/shader-gradient/image.png is excluded by !**/*.png
  • public/og/docs/components/stretchy-footer/image.png is excluded by !**/*.png
  • public/og/docs/components/tangle-footer/image.png is excluded by !**/*.png
  • public/og/docs/getting-started/image.png is excluded by !**/*.png
  • public/og/docs/image.png is excluded by !**/*.png
📒 Files selected for processing (10)
  • .github/workflows/deploy-cloudflare.yml
  • app/layout.tsx
  • app/og/docs/[...slug]/route.tsx
  • lib/og-image.tsx
  • lib/og-paths.mjs
  • lib/seo.ts
  • package.json
  • scripts/build-og-images.mjs
  • scripts/og-lib.mjs
  • tests/og.test.mjs
💤 Files with no reviewable changes (2)
  • app/og/docs/[...slug]/route.tsx
  • lib/og-image.tsx

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change moves documentation Open Graph image generation from a runtime route to a build-time PNG pipeline. It adds shared path helpers, updates page metadata, runs generation during builds, removes the old route and renderer, and adds tests for the static image pipeline.

Changes

Static documentation OG images

Layer / File(s) Summary
OG path and metadata contract
lib/og-paths.mjs, lib/seo.ts, app/layout.tsx
Adds shared image dimensions and helpers for URL and public-file paths. Page metadata now references static PNG images with dimensions and MIME type.
OG image generation pipeline
scripts/og-lib.mjs, scripts/build-og-images.mjs
Discovers documentation pages, parses metadata, renders branded PNG images, and writes them to the public directory.
Build and route migration
package.json, .github/workflows/deploy-cloudflare.yml, app/og/docs/[...slug]/route.tsx, lib/og-image.tsx
Runs OG generation before application and Cloudflare builds. Removes the runtime documentation OG route and renderer.
Static OG pipeline validation
tests/og.test.mjs
Tests path helpers, metadata conventions, slug and frontmatter parsing, generated PNG dimensions, documentation coverage, and removal of runtime OG imports and routes.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant BuildScript
  participant OgLibrary
  participant Docs
  participant PublicFiles
  BuildScript->>OgLibrary: call buildOgImages()
  OgLibrary->>Docs: discover and parse MDX pages
  OgLibrary->>OgLibrary: render documentation pages as PNG
  OgLibrary->>PublicFiles: write static OG image files
  PublicFiles-->>BuildScript: return generated file paths
Loading

Merge Risk: ⚪ Minimal · up to 75933

The static OG-image migration is ready to merge: documentation card generation completes successfully and deployment paths generate the required assets before building.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 6 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: serving static Open Graph images on Cloudflare instead of relying on the runtime route.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 6 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/fix-og-image-d25d

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Cloudflare preview is ready.

Preview https://pr-30-23rd-dev.radiumcoders.workers.dev
This commit https://c9500f2f-23rd-dev.radiumcoders.workers.dev

Production (23rd.dev) is unchanged. This preview URL stays the same as you push to this PR.

@radiumcoders
radiumcoders marked this pull request as ready for review September 13, 2026 10:57
@radiumcoders
radiumcoders merged commit 53d0e00 into main Sep 13, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants