Skip to content

Fix OG image 500s and stop install rate limits logging as errors#398

Merged
leerob merged 1 commit into
mainfrom
cursor/og-image-hardening-and-install-rate-limit
May 26, 2026
Merged

Fix OG image 500s and stop install rate limits logging as errors#398
leerob merged 1 commit into
mainfrom
cursor/og-image-hardening-and-install-rate-limit

Conversation

@leerob
Copy link
Copy Markdown
Collaborator

@leerob leerob commented May 26, 2026

Summary

  • Fix Open Graph image route 500s (~5% of OG traffic) caused by relative logo/avatar URLs and Satori's strict layout requirements.
  • Normalize image src to absolute URLs via resolveOgImageUrl, add explicit display: flex on multi-child nodes, and set Cache-Control on ImageResponse so social crawlers hit cached PNGs instead of regenerating.
  • Add revalidate = 86400 to the OG routes. Listing OG routes (/, /plugins, /members, /login, /companies, /plugins/new) prerender as ISR-static; the slug routes (/plugins/[slug], /u/[slug], /c/[slug]) stay dynamic but still benefit from response caching.
  • track-install now returns a non-throwing result ({ tracked } / { rateLimited }) instead of throwing ActionError, so expected install rate limiting no longer floods Vercel error-level logs. The client only increments the count on success and shows a toast when rate limited.

Background

Production log analysis on anysphere/cursor-directory surfaced two recurring issues:

  • /plugins/[slug]/opengraph-image returning 500 (Image source must be an absolute URL, Expected <div> to have explicit "display: flex").
  • High volume of Action error: Rate limit exceeded error logs from the track-install server action — expected UX, but logged as errors.

Test plan

  • npm run build succeeds; build route table shows listing OG routes as Static (, revalidate 1d) and slug OG routes as Dynamic (ƒ).
  • prerender-manifest.json confirms initialRevalidateSeconds: 86400 and Cache-Control headers on prerendered OG routes.
  • Verify social preview images render for a plugin with a relative logo URL.
  • Confirm hitting the install rate limit shows a toast and does not emit an error-level log.

Made with Cursor


Note

Low Risk
Targeted rendering and logging/UX fixes; install counting behavior is slightly stricter (no optimistic bump on rate limit) but RPC path is unchanged on success.

Overview
Fixes Open Graph route 500s and cuts noise from expected install rate limits in production logs.

OG images now use resolveOgImageUrl so Satori gets absolute http(s) URLs when logos/avatars are stored as site-relative paths. Several OG JSX nodes gain explicit display: flex for Satori layout rules. createOGResponse sets day-long Cache-Control on PNG responses, and OG routes export revalidate = 86400 so listing images can ISR and crawlers reuse cached output.

track-install stops throwing on rate limit: it returns { tracked: true } or { tracked: false, rateLimited: true }. plugin-detail only bumps the install count when tracking succeeds and shows a toast when rate limited, instead of optimistically incrementing and logging server errors.

Reviewed by Cursor Bugbot for commit 913f049. Bugbot is set up for automated code reviews on this repo. Configure here.

OG image routes were 500ing (~5% of traffic) on relative logo URLs and
Satori layout constraints. Normalize image src to absolute URLs, add
explicit display:flex on multi-child nodes, and set Cache-Control plus a
1d revalidate so social crawlers hit cached PNGs.

track-install now returns a non-throwing rate-limit result instead of
throwing ActionError, so expected rate limiting no longer shows up as
error-level logs. The client only increments the count on success and
toasts on rate limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

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

Project Deployment Actions Updated (UTC)
cursor-directory Ready Ready Preview, Comment May 26, 2026 5:06pm

Request Review

@leerob leerob marked this pull request as ready for review May 26, 2026 17:02
@leerob leerob merged commit b7438eb into main May 26, 2026
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.

1 participant