Adding Open Graph images to your website is one of the highest-impact, lowest-effort SEO and social media optimizations you can make. This guide walks through the exact steps for every major web framework and CMS.
What You Need
Before you start, you need two things:
- An OG image file. A 1200 × 630 pixel PNG or JPG under 1 MB. See our OG image size guide for dimension details, or generate one with AI on Pixola.
- The image hosted at a public URL. The URL must be absolute (starting with
https://) and accessible without authentication.
Plain HTML
Add these meta tags inside the <head> section of your HTML page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Your Page Title</title>
<!-- Open Graph -->
<meta property="og:title" content="Your Page Title" />
<meta property="og:description" content="A short description of the page." />
<meta property="og:image" content="https://yoursite.com/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Description of the image" />
<meta property="og:url" content="https://yoursite.com/page" />
<meta property="og:type" content="website" />
<!-- Twitter Card (optional, enhances Twitter previews) -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://yoursite.com/og-image.png" />
<meta name="twitter:image:alt" content="Description of the image" />
</head>
<body>
<!-- page content -->
</body>
</html>Required vs. Optional Tags
| Tag | Required? | Purpose |
|---|---|---|
og:image | Yes | The image URL |
og:image:width | Recommended | Helps platforms render faster (avoids re-fetching to measure) |
og:image:height | Recommended | Same as width |
og:image:alt | Recommended | Accessibility — describes the image for screen readers |
og:image:type | Optional | MIME type (image/png, image/jpeg) |
Next.js (App Router)
Next.js App Router has built-in support for Open Graph images through the metadata API. There are two approaches:
Option 1: Static Metadata
Export a metadata object from your page or layout. Next.js generates the correct meta tags automatically:
// app/page.tsx (or any page/layout)
import type { Metadata } from "next"
export const metadata: Metadata = {
title: "Your Page Title",
description: "A short description.",
openGraph: {
title: "Your Page Title",
description: "A short description.",
url: "https://yoursite.com",
siteName: "Your Site",
images: [
{
url: "https://yoursite.com/og-image.png",
width: 1200,
height: 630,
alt: "Description of the image",
},
],
type: "website",
},
twitter: {
card: "summary_large_image",
images: ["https://yoursite.com/og-image.png"],
},
}
export default function Page() {
return <main>Your page content</main>
}Option 2: Dynamic OG Images with next/og
Next.js can generate OG images on the fly using the ImageResponse API. Create an opengraph-image.tsx file in your route directory:
// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from "next/og"
export const size = { width: 1200, height: 630 }
export const contentType = "image/png"
export default async function OGImage({
params,
}: {
params: { slug: string }
}) {
return new ImageResponse(
(
<div
style={{
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
color: "white",
fontSize: 48,
fontWeight: 700,
}}
>
{params.slug.replace(/-/g, " ")}
</div>
),
{ ...size }
)
}This approach is powerful for blogs and dynamic content where each page needs a unique OG image. Next.js handles caching and serving the generated images.
React (Single-Page App)
Standard React SPAs (Create React App, Vite) are tricky for OG images because social media crawlers do not execute JavaScript. The crawlers see the initial HTML, which typically contains only a root <div>.
Options:
- Pre-render your pages using a tool like
react-snaporprerender.io. This generates static HTML with meta tags that crawlers can read. - Switch to Next.js or another server-rendered framework. This is the most reliable solution.
- Use a meta tag service like prerender.io or Cloudflare Workers to inject OG tags for bot traffic.
If you are building a new project and want good OG image support, use a framework with server-side rendering from the start.
WordPress
WordPress does not include Open Graph tags by default. Use an SEO plugin to add them:
Yoast SEO
- Install and activate the Yoast SEO plugin.
- Edit any post or page. Scroll to the Yoast SEO section.
- Click the “Social” tab (share icon).
- Upload or select an image under “Facebook image.” This image is used for the
og:imagetag. - Optionally set a different Twitter image under the Twitter tab.
If you do not set a social image, Yoast falls back to the Featured Image. If that is not set either, it falls back to the first image in the post content.
Rank Math
- Install and activate Rank Math.
- Edit a post or page, open the Rank Math panel.
- Go to the “Social” tab.
- Upload your OG image under “Facebook Thumbnail.”
Manual (Without a Plugin)
Add OG tags directly in your theme's header.php or via a custom plugin:
// In functions.php or a custom plugin
function add_og_meta_tags() {
if (is_singular()) {
$image = get_the_post_thumbnail_url(get_the_ID(), 'full');
if ($image) {
echo '<meta property="og:image" content="' . esc_url($image) . '" />';
echo '<meta property="og:image:width" content="1200" />';
echo '<meta property="og:image:height" content="630" />';
}
}
}
add_action('wp_head', 'add_og_meta_tags');Gatsby
Use Gatsby's Head API (Gatsby 4.19+) or the react-helmet approach for older versions:
// Using Gatsby Head API
export function Head() {
return (
<>
<meta property="og:image" content="https://yoursite.com/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Page description" />
</>
)
}Astro
Astro makes OG tags straightforward. Add them to your layout or page frontmatter component:
---
// src/layouts/BaseLayout.astro
const { title, description, image } = Astro.props
---
<html>
<head>
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image || "https://yoursite.com/og-default.png"} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
</head>
<body><slot /></body>
</html>Shopify
Shopify themes typically include OG tags in the theme.liquid layout. Most modern themes handle this automatically using the product image or page featured image. To customize:
- Go to Online Store > Themes > Edit code.
- Open
theme.liquid(or your theme's head partial). - Look for existing
og:imagetags and modify them, or add them if missing.
Testing Your OG Images
After adding OG tags, test them before sharing publicly:
- View page source. Search for
og:imagein your page's HTML to confirm the tags are present. - Open the image URL directly. Paste the
og:imageURL in a browser to verify it loads. - Use Facebook Sharing Debugger. Paste your page URL to see exactly what Facebook will render.
- Use LinkedIn Post Inspector. Test your LinkedIn preview and refresh the cache.
- Share in a private message. Send your URL to yourself on Slack, Discord, or Messages to see the live preview.
If your OG image is not showing after adding the tags, check our troubleshooting guide for OG image issues.
Should Every Page Have Its Own OG Image?
Ideally, yes. Pages with unique OG images get higher click-through rates than pages sharing a single site-wide default. At minimum:
- Homepage: Brand-focused OG image with your logo and tagline.
- Blog posts: Unique image per post featuring the title and a relevant visual.
- Product pages: Product photo or feature image.
- Landing pages: Campaign-specific image matching the page's message.
For sites with many pages, consider automating OG image generation using tools like Pixola's AI OG Image Generator or Next.js's built-in ImageResponse API.
Implementation Checklist
- Image is 1200 × 630 px, under 1 MB, PNG or JPG
og:imageuses an absolute HTTPS URLog:image:widthandog:image:heightare setog:image:altprovides a text descriptiontwitter:cardis set tosummary_large_image- Image URL is publicly accessible (no auth required)
- Tested with Facebook Sharing Debugger
- Tested with LinkedIn Post Inspector
- Preview checked on mobile