Skip to content

perf(docs): load OG image fonts from disk instead of Google Fonts#7887

Open
aidankmcalister wants to merge 2 commits intomainfrom
perf/DR-8019-og-fonts-from-disk
Open

perf(docs): load OG image fonts from disk instead of Google Fonts#7887
aidankmcalister wants to merge 2 commits intomainfrom
perf/DR-8019-og-fonts-from-disk

Conversation

@aidankmcalister
Copy link
Copy Markdown
Member

@aidankmcalister aidankmcalister commented May 10, 2026

What & why

apps/docs/src/app/og/[...slug]/route.tsx fetched Barlow, Inter, and JetBrains Mono from Google Fonts on every cold start (6 network calls per cold start). Bundle the TTFs in apps/docs/public/fonts/ and read them with node:fs/promises instead.

Tested

curl http://localhost:3001/docs/og/accelerate/image.png
# HTTP 200, 1200x630 PNG, Barlow + Inter render correctly

curl http://localhost:3001/docs/og/management-api/endpoints/regions/get-regions/image.png
# HTTP 200, 1200x630 PNG, Barlow + Inter + JetBrains Mono render correctly

pnpm check passes for apps/docs.

Linear: DR-8019

Summary by CodeRabbit

  • Chores
    • Improved OG image generation by switching font loading from external sources to local font files. This increases reliability, reduces runtime network dependence, and can improve performance and consistency of link preview rendering across the documentation site.

Review Change Stack

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment May 10, 2026 11:55pm
docs Ready Ready Preview, Comment May 10, 2026 11:55pm
eclipse Ready Ready Preview, Comment May 10, 2026 11:55pm
site Ready Ready Preview, Comment May 10, 2026 11:55pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6b0b758d-a3a4-422e-b26d-dfe34f7a37da

📥 Commits

Reviewing files that changed from the base of the PR and between 0831920 and 46d59c8.

📒 Files selected for processing (1)
  • apps/docs/src/app/og/[...slug]/route.tsx

Walkthrough

This PR rewires OG image font loading from Google Fonts HTTP fetch to local file I/O. Font metadata and type definitions shift to .ttf filenames and Buffer, Node.js imports enable file reading, and the getFonts() function reads from disk instead of the network, maintaining the existing promise cache and error semantics.

Changes

Font Loading Migration

Layer / File(s) Summary
Font Configuration
apps/docs/src/app/og/[...slug]/route.tsx
FONT_DEFINITIONS updated to reference local .ttf filenames; loader now converts Node Buffer to ArrayBuffer for in-memory font payload.
Node.js Imports & Cleanup
apps/docs/src/app/og/[...slug]/route.tsx
Added readFile from node:fs/promises and node:path; removed GOOGLE_FONT_RESOURCE_REGEX.
Font Loading Implementation
apps/docs/src/app/og/[...slug]/route.tsx
getFonts() replaced with a local-file-based loader reading .ttf binaries from process.cwd()/public/fonts, converting bytes to ArrayBuffer, and preserving promise-cache and error-reset behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. 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 'perf(docs): load OG image fonts from disk instead of Google Fonts' directly and accurately describes the main change: replacing runtime Google Fonts fetching with local disk-based font loading for performance.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@argos-ci
Copy link
Copy Markdown

argos-ci Bot commented May 10, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - May 11, 2026, 12:01 AM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/docs/src/app/og/[...slug]/route.tsx (1)

280-294: ⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Fix: Serverless functions cannot access public/ files at runtime on Vercel.

The fonts directory exists in public/fonts/, but here's the critical issue: because this route uses export const revalidate = false (on-demand ISR), it reads fonts at request time, not build time. In Vercel's serverless environment, the public/ folder is deployed to CDN and is not available on the function's filesystem—readFile() will fail with ENOENT in production.

Move font files to a location bundled with the route handler. The recommended pattern for Next.js app router:

Example fix
- data: await readFile(path.join(process.cwd(), "public", "fonts", file)),
+ data: await readFile(new URL(`./fonts/${file}`, import.meta.url)),

This requires moving fonts to apps/docs/src/app/og/fonts/ so they're bundled with the route file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/docs/src/app/og/`[...slug]/route.tsx around lines 280 - 294, getFonts
currently reads from process.cwd()/public which fails in Vercel serverless
because public/ is served from the CDN and not available at runtime; move the
font files into the route bundle (e.g., apps/docs/src/app/og/fonts/) and update
getFonts to load them from the bundled relative folder instead of process.cwd()
(stop using "public" path and process.cwd()); keep the same FONT_DEFINITIONS
entries but change their file paths to reference the new bundled filenames and
read them via path.join(__dirname or the route file directory, "fonts", file) or
import them so they are included at build time, ensuring fontCache logic remains
the same but now reads from the bundled assets rather than public/.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/docs/src/app/og/`[...slug]/route.tsx:
- Around line 63-68: The LoadedFont type's data field must be ArrayBuffer (not
Buffer) to match next/og ImageResponse expectations; change LoadedFont { data:
Buffer } to { data: ArrayBuffer } and when loading fonts (where you currently
call fs.readFile or similar that returns a Buffer) convert the Buffer to an
ArrayBuffer (e.g., Buffer.toArrayBuffer()) before assigning to LoadedFont.data;
also update any usages of LoadedFont.data (e.g., where fonts are passed into
ImageResponse or stored) to accept an ArrayBuffer.

---

Outside diff comments:
In `@apps/docs/src/app/og/`[...slug]/route.tsx:
- Around line 280-294: getFonts currently reads from process.cwd()/public which
fails in Vercel serverless because public/ is served from the CDN and not
available at runtime; move the font files into the route bundle (e.g.,
apps/docs/src/app/og/fonts/) and update getFonts to load them from the bundled
relative folder instead of process.cwd() (stop using "public" path and
process.cwd()); keep the same FONT_DEFINITIONS entries but change their file
paths to reference the new bundled filenames and read them via
path.join(__dirname or the route file directory, "fonts", file) or import them
so they are included at build time, ensuring fontCache logic remains the same
but now reads from the bundled assets rather than public/.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 79bf4f89-0d28-48b7-b764-8ef3c3c3f784

📥 Commits

Reviewing files that changed from the base of the PR and between d0a17f2 and 0831920.

⛔ Files ignored due to path filters (3)
  • apps/docs/public/fonts/Barlow-Bold.ttf is excluded by !**/*.ttf
  • apps/docs/public/fonts/Inter-Regular.ttf is excluded by !**/*.ttf
  • apps/docs/public/fonts/JetBrainsMono-Regular.ttf is excluded by !**/*.ttf
📒 Files selected for processing (1)
  • apps/docs/src/app/og/[...slug]/route.tsx

Comment thread apps/docs/src/app/og/[...slug]/route.tsx
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.

1 participant