Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Is this vibe coded? |
There was a problem hiding this comment.
Pull Request Overview
This PR adds dynamic Open Graph image generation functionality to the LMRouter documentation site. It implements a server-side image generation API endpoint that creates branded social media preview images.
Key changes:
- Added a new API endpoint
/api/og/route.tsxthat generates dynamic OG images with custom title, description, and type parameters - Updated documentation page metadata to include Open Graph and Twitter card configurations
- Added
@vercel/ogdependency for server-side image generation
Reviewed Changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/app/api/og/route.tsx | New API endpoint that generates dynamic OG images with LMRouter branding and custom content |
| src/app/(docs)/[[...slug]]/page.tsx | Enhanced metadata generation to include Open Graph and Twitter card configurations |
| package.json | Added @vercel/og dependency for image generation functionality |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| top: "30px", | ||
| left: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > | ||
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | ||
| </svg> | ||
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| top: "30px", | ||
| right: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > | ||
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | ||
| </svg> | ||
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| bottom: "30px", | ||
| left: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > |
There was a problem hiding this comment.
The corner decoration SVGs have duplicated styling properties (fill='white' and opacity='0.4'). Consider extracting these common properties into a shared style object or constant to reduce duplication and improve maintainability.
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| right: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| {/* | |
| Extracted common SVG properties for corner decorations | |
| */} | |
| {/* | |
| Define shared props for corner SVGs | |
| */} | |
| {/* | |
| Place this constant just before the SVGs | |
| */} | |
| {(() => { | |
| const cornerSvgProps = { fill: "white", opacity: "0.4" }; | |
| return ( | |
| <> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > | |
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| right: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > | |
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > |
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| top: "30px", | ||
| left: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > | ||
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | ||
| </svg> | ||
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| top: "30px", | ||
| right: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > | ||
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | ||
| </svg> | ||
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| bottom: "30px", | ||
| left: "30px", | ||
| width: "20px", | ||
| height: "20px", | ||
| }} | ||
| fill="white" | ||
| opacity="0.4" | ||
| > | ||
| <path d="M0,10 L10,10 L10,20" stroke="white" strokeWidth="2" fill="none" /> | ||
| </svg> | ||
| <svg | ||
| style={{ | ||
| position: "absolute", | ||
| bottom: "30px", |
There was a problem hiding this comment.
The corner decoration SVGs have duplicated styling properties (fill='white' and opacity='0.4'). Consider extracting these common properties into a shared style object or constant to reduce duplication and improve maintainability.
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| right: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| fill="white" | |
| opacity="0.4" | |
| > | |
| <path d="M0,10 L10,10 L10,20" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", | |
| {/* | |
| Shared SVG props for corner decorations | |
| */} | |
| {(() => { | |
| const cornerSvgProps = { | |
| fill: "white", | |
| opacity: "0.4", | |
| }; | |
| return ( | |
| <> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > | |
| <path d="M0,10 L10,10 L10,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| top: "30px", | |
| right: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > | |
| <path d="M10,10 L10,0 L20,0" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", | |
| left: "30px", | |
| width: "20px", | |
| height: "20px", | |
| }} | |
| {...cornerSvgProps} | |
| > | |
| <path d="M0,10 L10,10 L10,20" stroke="white" strokeWidth="2" fill="none" /> | |
| </svg> | |
| </> | |
| ); | |
| })()} | |
| <svg | |
| style={{ | |
| position: "absolute", | |
| bottom: "30px", |
| fill="white" | ||
| opacity="0.4" |
There was a problem hiding this comment.
The corner decoration SVGs have duplicated styling properties (fill='white' and opacity='0.4'). Consider extracting these common properties into a shared style object or constant to reduce duplication and improve maintainability.
| fill="white" | ||
| opacity="0.4" |
There was a problem hiding this comment.
The corner decoration SVGs have duplicated styling properties (fill='white' and opacity='0.4'). Consider extracting these common properties into a shared style object or constant to reduce duplication and improve maintainability.
| {/* Title */} | ||
| <h1 | ||
| style={{ | ||
| fontSize: title.length > 30 ? "56px" : "64px", |
There was a problem hiding this comment.
The magic number 30 for title length threshold should be extracted as a named constant to make the logic more maintainable and self-documenting.
| const page = source.getPage(params.slug); | ||
| if (!page) notFound(); | ||
|
|
||
| const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; |
There was a problem hiding this comment.
Is this envvar automatically set by Vercel?
No description provided.