8 months ago
Type-Safe meta images with Next.js and @vercel/og
If you've ever shared a page from your website only to find that the meta images are broken, you're not alone. This happened to me across all my projects—Glink, Sisi, Benji, and others. The issue stemmed from an outdated service that I was using to generate meta images, which stopped working. So, I decided to fix it once and for all using Next.js.
ÂThe Problem
Previously, I had a <MetaTags/> component that accepted some config that used an external service to generate images. Since this service no longer exists, all my meta images broke, leaving my pages with blank previews when shared.
The Solution
I decided to generate these images dynamically using an API route in Next.js. Here’s how I did it:
Â1. Creating an API Route for Image Generation
I set up an API route in pages/api/og/user.page.tsx. This API route dynamically generates images when requested.
(I'm using the .page extension for pages in next.js, but you probably don't, so that's fine. I'm doing this so I can include other types of files in my /pages folder)
ÂSample /api/og/user.page.tsx route that returns an image:
This route receives parameters like username and avatar, then generates an Open Graph (OG) image on the fly.
2. Implementing Meta Tags with Dynamic Images
I made the MetaTags component to dynamically generate the correct OG image URLs:
Using the MetaTags component
4. Automating API Route Type Generation
To ensure full type safety when using MetaTags with an og prop, I created a script that traverses the /api directory and generates a api-routes.ts file. This script scans for all API routes and extracts the parameters expected for each OG route.
Now, when using MetaTags, the og prop is fully type-safe, ensuring that only valid parameters can be passed.
You can find all the code snippets in this gist.
ÂFinal Thoughts
This setup ensures:
ÂNow, whenever I share a page, the OG images load correctly without relying on external services. If you have a similar issue, try this approach and let me know how it works for you!
Â