Improve generated Open Graph images - #1080
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe OG image generator now accepts page paths, truncates and sizes text dynamically, renders a structured header/content/footer layout, and adds a decorative traffic-line SVG. The route supplies documentation slugs as footer paths. ChangesOG image generation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant GET_handler
participant generateOGImage
participant OG_image_response
GET_handler->>generateOGImage: pass page metadata and path
generateOGImage->>generateOGImage: format text and compute footer URL
generateOGImage->>OG_image_response: render structured OG image
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
docs/src/app/og/[...slug]/generate.tsx (1)
67-75: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid the
insetshorthand for better Satori compatibility.Satori (the layout engine underlying Next.js OG images) can be inconsistent when parsing the
insetCSS shorthand, sometimes causing absolutely positioned elements to collapse. It is generally safer to use explicittop,right,bottom, andleftcoordinates.🛠️ Proposed refactor
<div style={{ display: 'flex', position: 'absolute', - inset: 24, + top: 24, + right: 24, + bottom: 24, + left: 24, border: '1px solid `#292929`', borderRadius: 5, }} />🤖 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 `@docs/src/app/og/`[...slug]/generate.tsx around lines 67 - 75, Update the absolutely positioned div’s style in the OG image generator to replace the inset shorthand with explicit top, right, bottom, and left properties, preserving the current 24px spacing on every side and all other styling.
🤖 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 `@docs/src/app/og/`[...slug]/generate.tsx:
- Around line 39-51: Update the footerPath assignment in generateOGImage to
distinguish an undefined path from an empty string: use the docs URL with the
path when path is defined, including "", and retain the base rybbit.com fallback
only when path is undefined.
- Around line 182-202: Update the SVG dimensions in the chart markup around the
TRAFFIC_LINE paths and endpoint circle so the circle at cx="330" with radius 3.5
is fully contained within the viewBox and rendered width; preserve the existing
chart geometry and styling while adding sufficient right-side space to prevent
clipping.
---
Nitpick comments:
In `@docs/src/app/og/`[...slug]/generate.tsx:
- Around line 67-75: Update the absolutely positioned div’s style in the OG
image generator to replace the inset shorthand with explicit top, right, bottom,
and left properties, preserving the current 24px spacing on every side and all
other styling.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: fe983644-cb5d-4bf3-807c-951de03c1abf
📒 Files selected for processing (2)
docs/src/app/og/[...slug]/generate.tsxdocs/src/app/og/[...slug]/route.tsx
| export function generateOGImage({ | ||
| title, | ||
| description, | ||
| logoSrc, | ||
| label, | ||
| path, | ||
| }: GenerateOGImageProps): ReactElement { | ||
| const displayTitle = truncateText(title, 96); | ||
| const displayDescription = description | ||
| ? truncateText(description, 156) | ||
| : undefined; | ||
| const footerPath = path ? `rybbit.com/docs/${path}` : 'rybbit.com'; | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Fix the footer URL for the docs root page.
When the image is generated for the root docs page (where path is an empty string ""), the current ternary condition evaluates to falsy and falls back to 'rybbit.com'. It should likely display 'rybbit.com/docs'. Check for undefined explicitly to handle the empty string case properly.
💡 Proposed fix
- const footerPath = path ? `rybbit.com/docs/${path}` : 'rybbit.com';
+ const footerPath = path !== undefined
+ ? `rybbit.com/docs${path ? `/${path}` : ''}`
+ : 'rybbit.com';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function generateOGImage({ | |
| title, | |
| description, | |
| logoSrc, | |
| label, | |
| path, | |
| }: GenerateOGImageProps): ReactElement { | |
| const displayTitle = truncateText(title, 96); | |
| const displayDescription = description | |
| ? truncateText(description, 156) | |
| : undefined; | |
| const footerPath = path ? `rybbit.com/docs/${path}` : 'rybbit.com'; | |
| export function generateOGImage({ | |
| title, | |
| description, | |
| logoSrc, | |
| label, | |
| path, | |
| }: GenerateOGImageProps): ReactElement { | |
| const displayTitle = truncateText(title, 96); | |
| const displayDescription = description | |
| ? truncateText(description, 156) | |
| : undefined; | |
| const footerPath = path !== undefined | |
| ? `rybbit.com/docs${path ? `/${path}` : ''}` | |
| : 'rybbit.com'; |
🤖 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 `@docs/src/app/og/`[...slug]/generate.tsx around lines 39 - 51, Update the
footerPath assignment in generateOGImage to distinguish an undefined path from
an empty string: use the docs URL with the path when path is defined, including
"", and retain the base rybbit.com fallback only when path is undefined.
| <svg | ||
| width="330" | ||
| height="44" | ||
| viewBox="0 0 330 44" | ||
| fill="none" | ||
| aria-hidden="true" | ||
| > | ||
| <path | ||
| d={`${TRAFFIC_LINE} L330 44 L0 44 Z`} | ||
| fill="rgba(179, 191, 255, 0.07)" | ||
| /> | ||
| <path | ||
| d={TRAFFIC_LINE} | ||
| stroke="#b3bfff" | ||
| strokeWidth="2" | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| /> | ||
| <circle cx="330" cy="5" r="3.5" fill="#b3bfff" /> | ||
| </svg> | ||
| </div> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Prevent the circle from being clipped by the SVG boundary.
The SVG viewBox and width end at 330. Because the circle is positioned at cx="330" with a radius of 3.5, its right half extends to 333.5 and will be visibly clipped by the default overflow="hidden" behavior of the SVG element.
🎨 Proposed fix to make the overflow visible
<svg
width="330"
height="44"
viewBox="0 0 330 44"
fill="none"
aria-hidden="true"
+ style={{ overflow: 'visible' }}
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <svg | |
| width="330" | |
| height="44" | |
| viewBox="0 0 330 44" | |
| fill="none" | |
| aria-hidden="true" | |
| > | |
| <path | |
| d={`${TRAFFIC_LINE} L330 44 L0 44 Z`} | |
| fill="rgba(179, 191, 255, 0.07)" | |
| /> | |
| <path | |
| d={TRAFFIC_LINE} | |
| stroke="#b3bfff" | |
| strokeWidth="2" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| /> | |
| <circle cx="330" cy="5" r="3.5" fill="#b3bfff" /> | |
| </svg> | |
| </div> | |
| <svg | |
| width="330" | |
| height="44" | |
| viewBox="0 0 330 44" | |
| fill="none" | |
| aria-hidden="true" | |
| style={{ overflow: 'visible' }} | |
| > | |
| <path | |
| d={`${TRAFFIC_LINE} L330 44 L0 44 Z`} | |
| fill="rgba(179, 191, 255, 0.07)" | |
| /> | |
| <path | |
| d={TRAFFIC_LINE} | |
| stroke="`#b3bfff`" | |
| strokeWidth="2" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| /> | |
| <circle cx="330" cy="5" r="3.5" fill="`#b3bfff`" /> | |
| </svg> | |
| </div> |
🤖 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 `@docs/src/app/og/`[...slug]/generate.tsx around lines 182 - 202, Update the
SVG dimensions in the chart markup around the TRAFFIC_LINE paths and endpoint
circle so the circle at cx="330" with radius 3.5 is fully contained within the
viewBox and rendered width; preserve the existing chart geometry and styling
while adding sufficient right-side space to prevent clipping.
Summary by CodeRabbit