Make your links look great when people share them. The single biggest free marketing trick.
When someone pastes your link into a tweet, a Slack message, or an iMessage, the platform shows a preview card. That card has three things: a title, a description, and a big image. The image takes up 70% of the visual real estate.
Without an OG image
Your Site
codebooks.ai
Looks broken. People scroll past.
With a great OG image
CodeBooks — The AI Coder's Library
codebooks.ai
Looks legit. People click.
The simplest version: one OG image for your whole site. Make it once in Figma or Canva, save it, and you're done.
Open Figma or Canva. Create a 1200×630 frame.
Add your logo, your tagline, and a brand-y background. Keep text big — small text is unreadable in previews.
Export as PNG (or JPG for smaller file size).
Save it to /public/og-image.png in your project.
Add it to the metadata in app/layout.tsx (your AI tool can do this in one prompt).
ADD A STATIC OG IMAGE
"I have an image at /public/og-image.png that's 1200×630. Use it as the default preview image for my whole site — the one that shows up when someone shares any page on social media or in a message app. Include a short title, description, and alt text so it looks good on Twitter, LinkedIn, Facebook, and iMessage."
Static is fine for the homepage. But if you have a blog or a product catalog, you want a unique image for each page — with the post title or product name baked in.
Next.js has a built-in feature for this called opengraph-image.tsx. You write a tiny React component that returns an image, and Next generates a real PNG on demand. No image editor needed.
How dynamic OG works in Next.js
ADD DYNAMIC OG IMAGES TO MY BLOG
"Every blog post on my site should get its own custom preview image — the one that shows up when someone shares the post on social media. Make each image 1200×630 and include the post title (nice and large), the author name, the publish date, and my brand logo. Use a purple gradient background with white text and my Bricolage font. Generate these automatically for every post."
OG images don't work on their own — they need specific HTML meta tags so platforms know where to find them. Next.js handles this through the metadata API.
The 6 tags every page needs
You don't write these by hand. Next.js generates them from the metadata object you export from each page.
Most OG images look bad because they break one of these rules. Follow them and yours will stand out.
Make text huge
Headline should be at least 60px. Subtitle 30px. People see it as a thumbnail — small text is invisible.
High contrast
Light text on dark background or vice versa. Never gray text on a gray background.
One focal point
Don't cram in 5 things. Pick the headline OR the product photo, not both.
Brand color always visible
Use your signature color in every OG image. Builds recognition over time.
No tiny logos in the corner
If the logo matters, make it big. If not, leave it off.
Test in dark mode
iMessage shows previews on a dark background. Make sure yours doesn't disappear.
You updated your OG image. You shared the link. The old image is still showing. Welcome to caching hell.
Force-refresh your previews
• X (Twitter): cards-dev.twitter.com/validator — paste URL, click Preview Card
• LinkedIn: linkedin.com/post-inspector — paste URL, click Inspect
• Facebook: developers.facebook.com/tools/debug — paste URL, click "Scrape Again"
• iMessage / Slack: add a fake query parameter (?v=2) to the URL
Image doesn't show up at all
Your og:image URL is relative (/og.png) instead of absolute (https://yoursite.com/og.png). Platforms need the full URL.
Image works on X but not LinkedIn
LinkedIn requires twitter:card to be set to "summary_large_image" AND og:image to be at least 1200×630.
Custom font doesn't render in dynamic OG
ImageResponse can't use Google Fonts at runtime. Bundle the font file (.ttf/.otf) in your project and load it manually.
Old image keeps showing after update
Aggressive caching. Use the platform debugger above to force a refresh, or change the filename.
You write a great blog post and tweet a link. Without an OG image, your tweet looks broken — just a URL. With a custom OG image showing the post title in big bold letters, your tweet stops the scroll and gets clicks. The fix is one prompt that creates a dynamic OG image generator for every blog post in your project.
Build this with AI
"Add dynamic OG image generation to every blog post in my Next.js project. Posts live at /blog/[slug] and the data comes from my posts table in Supabase. Each OG image should be 1200×630, show the post title in 72px Bricolage, the author name and publish date below in 24px, and my brand logo in the bottom right. Use a purple-to-pink gradient background. Use ImageResponse from next/og."
OG IMAGE FOR EVERY PRODUCT PAGE
"My product pages live at /products/[slug]. Generate a dynamic OG image for each one showing the product photo on the left and the product name + price on the right. Use my brand colors. Cache aggressively."
ADD A SHARE BUTTON
"On every blog post page, add a row of share buttons (X, LinkedIn, Facebook, copy link). They should pre-fill the post title and URL when clicked. Make sure the X share also includes my @handle for attribution."
OG IMAGE PREVIEW IN MY CMS
"In my admin area where I edit blog posts, show a live preview of the OG image as I type the title. It should look like a real X card so I can see what the share will look like before publishing."