fix(og): generate static PNG OG images for landing and guides static exports#2417
Merged
Merged
Conversation
…exports - Root cause: Next.js static exports write OG image data as .body/.meta files (internal format) that Cloudflare Workers serves as raw bytes without Content-Type: image/png, so crawlers never see valid images. - Fix: pre-build scripts (scripts/generate-og-images.ts) use ImageResponse from next/og in Node.js to render the same JSX and write real .png files to public/ before next build runs. - Landing: generates public/og-image.png - Guides: generates public/og-image.png + public/og/[slug].png for all 39 posts - Extracted metadata into lib/metadata.ts (landing/guides) so it can be imported in tests without hitting next/font/google. - Added explicit openGraph.images + twitter.images in all layout metadata and per-slug generateMetadata so <meta> tags are always present regardless of how Next.js resolves file-convention images. - Vitest tests (apps/landing/__tests__/og-image.test.ts, apps/guides/__tests__/og-image.test.ts) verify: PNG exists, valid PNG signature, correct 1200x630 dimensions, >1KB size, metadata contains /og-image.png, per-slug metadata contains /og/[slug].png. - Root package.json: added test:landing and test:guides commands. Agent-Logs-Url: https://github.com/PackRat-AI/PackRat/sessions/313eb9d8-a587-40c6-b39e-368e98256d3e Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/PackRat-AI/PackRat/sessions/313eb9d8-a587-40c6-b39e-368e98256d3e Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
Contributor
Deploying packrat-landing with
|
| Latest commit: |
2dbfcb6
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://56e6f766.packrat-landing.pages.dev |
| Branch Preview URL: | https://copilot-fix-open-graph-image.packrat-landing.pages.dev |
Copilot created this pull request from a session on behalf of
andrew-bierman
May 13, 2026 07:13
View session
Contributor
Deploying packrat-guides with
|
| Latest commit: |
2dbfcb6
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://be5b8cac.packrat-guides-6gq.pages.dev |
| Branch Preview URL: | https://copilot-fix-open-graph-image.packrat-guides-6gq.pages.dev |
…port Agent-Logs-Url: https://github.com/PackRat-AI/PackRat/sessions/944edff9-cded-404a-97ee-df2523683e53 Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
Contributor
Coverage Report for API Unit Tests Coverage (./packages/api)
File CoverageNo changed files found. |
Contributor
Coverage Report for Expo Unit Tests Coverage (./apps/expo)
File CoverageNo changed files found. |
Agent-Logs-Url: https://github.com/PackRat-AI/PackRat/sessions/e8718b89-10d4-451e-96cf-bc9bba4594e7 Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
andrew-bierman
approved these changes
May 13, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes Open Graph images work correctly for the apps/landing and apps/guides static exports by generating real PNG files into public/ at build time, and wiring metadata/tests around those outputs.
Changes:
- Add pre-build Bun scripts to render
next/ogImageResponseoutput into static PNGs under each app’spublic/directory. - Update Landing/Guides metadata and OG image routes to reuse shared OG JSX/constants and point metadata at the generated PNG paths.
- Add Vitest configs + tests to validate generated PNG existence/format/dimensions, plus ignore generated PNGs in git.
Reviewed changes
Copilot reviewed 21 out of 23 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds root-level test:guides / test:landing commands. |
| bun.lock | Locks new workspace deps (notably Vitest in landing/guides). |
| apps/landing/vitest.config.ts | Introduces Vitest config (alias + test discovery) for Landing tests. |
| apps/landing/scripts/generate-og-images.ts | New pre-build generator that writes public/og-image.png. |
| apps/landing/package.json | Runs OG generation before next build; adds generate-og-images + test scripts; adds Vitest devDep. |
| apps/landing/lib/og-image.tsx | Centralizes Landing OG JSX + shared constants. |
| apps/landing/lib/metadata.ts | Centralizes Landing Metadata, including /og-image.png references. |
| apps/landing/app/twitter-image.tsx | Refactors to use shared OG element/constants. |
| apps/landing/app/opengraph-image.tsx | Refactors to use shared OG element/constants. |
| apps/landing/app/layout.tsx | Switches to landingMetadata export. |
| apps/landing/tests/og-image.test.ts | Adds tests to generate/validate Landing OG PNG + metadata image URLs. |
| apps/guides/vitest.config.ts | Introduces Vitest config (alias + timeouts) for Guides tests. |
| apps/guides/scripts/generate-og-images.ts | New pre-build generator that writes root + per-post PNGs (public/og/*.png). |
| apps/guides/package.json | Runs OG generation as part of build; adds generate-og-images + test scripts; adds Vitest devDep. |
| apps/guides/lib/og-image.tsx | Centralizes Guides OG JSX (root + per-post) + shared constants. |
| apps/guides/lib/metadata.ts | Centralizes Guides Metadata, including /og-image.png references. |
| apps/guides/app/twitter-image.tsx | Refactors to use shared OG element/constants. |
| apps/guides/app/opengraph-image.tsx | Refactors to use shared OG element/constants. |
| apps/guides/app/layout.tsx | Switches to guidesMetadata export. |
| apps/guides/app/guide/[slug]/page.tsx | Adds per-slug metadata image URLs pointing at /og/[slug].png. |
| apps/guides/app/guide/[slug]/opengraph-image.tsx | Refactors per-slug OG route to use shared element/constants. |
| apps/guides/tests/og-image.test.ts | Adds tests to generate/validate root + per-post Guides OG PNGs + metadata URLs. |
| .gitignore | Ignores generated OG PNG outputs for landing/guides. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "private": true, | ||
| "scripts": { | ||
| "build": "bun run build-content && next build", | ||
| "build": "bun run generate-og-images && bun run build-content && next build", |
| return Buffer.from(await response.arrayBuffer()); | ||
| } | ||
|
|
||
| async function generateOgImages(): Promise<void> { |
andrew-bierman
pushed a commit
that referenced
this pull request
May 14, 2026
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.
apps/guides/__tests__/og-image.test.ts— usebuf.readUInt32BE()instead of index access (noUncheckedIndexedAccess), add guard forposts[0]apps/landing/__tests__/og-image.test.ts— usebuf.readUInt32BE()instead of index access.gitignore(apps/landing/public/og-image.png,apps/guides/public/og-image.png,apps/guides/public/og/)bun check-typespasses cleanly