How to Add Open Graph Tags to WordPress Without a Plugin (2026 Guide)
If you landed here, you already know the deal: you pasted your WordPress post link into Slack, LinkedIn, or iMessage and got back an ugly text-only preview with no image. The fix is Open Graph tags. The wrong fix is installing Yoast, Rank Math, or a dedicated OG plugin for a 12-line problem.
This guide shows the exact code, where it goes, and how to verify it works — all without a single plugin. Total time: under 5 minutes.
Why Skip the Plugin
Three reasons I tell every client to avoid the plugin route for Open Graph tags alone:
- Performance. Yoast adds ~45KB to every page load and runs on every request. For OG tags you need ~2KB of output.
- Conflicts. Most OG plugins fight with caching layers (WP Rocket, LiteSpeed), CDNs, and each other. Manual tags do not.
- Control. You decide exactly what gets emitted. No mystery attributes, no surprise updates breaking your Facebook preview.
The only reason to use a plugin is if you also need full SEO title/meta management. For OG alone, code wins.
The Code (Paste This Into functions.php)
Open your active theme's functions.php — or better, a child theme or a site-specific plugin file at wp-content/mu-plugins/og-tags.php. Paste:
add_action('wp_head', 'custom_open_graph_tags', 5);
function custom_open_graph_tags() {
if (is_singular()) {
global $post;
$title = get_the_title();
$description = has_excerpt()
? wp_strip_all_tags(get_the_excerpt())
: wp_trim_words(wp_strip_all_tags($post->post_content), 30, '...');
$url = get_permalink();
$image = has_post_thumbnail()
? get_the_post_thumbnail_url($post->ID, 'full')
: 'https://yoursite.com/default-og.jpg';
$site_name = get_bloginfo('name');
} else {
$title = get_bloginfo('name');
$description = get_bloginfo('description');
$url = home_url();
$image = 'https://yoursite.com/default-og.jpg';
$site_name = get_bloginfo('name');
}
?>
<meta property="og:type" content="<?php echo is_singular() ? 'article' : 'website'; ?>" />
<meta property="og:title" content="<?php echo esc_attr($title); ?>" />
<meta property="og:description" content="<?php echo esc_attr($description); ?>" />
<meta property="og:url" content="<?php echo esc_url($url); ?>" />
<meta property="og:image" content="<?php echo esc_url($image); ?>" />
<meta property="og:site_name" content="<?php echo esc_attr($site_name); ?>" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="<?php echo esc_attr($title); ?>" />
<meta name="twitter:description" content="<?php echo esc_attr($description); ?>" />
<meta name="twitter:image" content="<?php echo esc_url($image); ?>" />
<?php
}Replace yoursite.com/default-og.jpg with your real fallback image URL. Save. Done.
What Each Tag Actually Does
A lot of tutorials dump the code and leave. Here is what matters in 2026:
og:type—articlefor posts,websitefor everything else. Facebook uses this to decide card layout.og:image— minimum 1200×630 pixels, under 8MB, JPG or PNG. Smaller images get cropped or rejected entirely by LinkedIn.og:description— 65-155 characters is the sweet spot. Facebook truncates at ~300, LinkedIn at ~200, iMessage shows ~140.twitter:card—summary_large_imagegives you the big hero image.summarygives a thumbnail. Always pick the first unless your image is tiny.
Critical: Twitter (now X) falls back to Open Graph tags if Twitter Card tags are missing. But if you set both, Twitter-specific tags win. Set both, always.
Fixing the "Image Not Updating" Problem
The #1 bug report after adding OG tags: "I changed the image but Facebook still shows the old one." This is not your code. It is Facebook's aggressive caching.
Fix:
- Go to Facebook Sharing Debugger.
- Paste the URL.
- Click "Scrape Again" twice. Yes, twice — the first scrape often returns stale data.
For LinkedIn, use the LinkedIn Post Inspector at linkedin.com/post-inspector/. For Twitter/X, just post the URL — they no longer have a public card validator as of 2023.
Pro tip: append a cache-busting query string (?v=2) to the image URL inside og:image when you absolutely need an update. Facebook treats it as a new asset.
Verifying It Worked
Three-step check:
- View source on any post. Search for
og:title. You should see all 10 tags. - Facebook Debugger — paste URL, confirm image, title, description render correctly.
- iMessage test — send the link to yourself. This catches Twitter-card edge cases nothing else does.
If you see duplicates, another plugin (usually Jetpack or an SEO plugin) is also emitting OG tags. Remove it or add remove_action('wp_head', ...) with the right hook.
Generating the Perfect OG Image
Your tags are only as good as the image they point to. A 1200×630 JPG with readable text, logo, and brand colors will double your click-through on social shares versus a generic hero crop.
You can design these manually in Figma, or use a free OG image generator that produces 1200×630 PNGs with zero signup. I use it for client sites that do not warrant a full design system.
If you are starting from scratch, keep these rules in mind:
- Text: 40-60px minimum. Anything smaller disappears on mobile.
- Safe zone: keep critical content in the center 1000×500 area. LinkedIn crops edges.
- Contrast ratio 4.5:1 minimum between text and background.
- No more than 7 words of headline. Less is better.
Sibling Tools You Will Probably Need Next
Once your OG tags ship, the next problems that show up:
- Free Email Signature Generator — put the new brand image in your team's email footers so every reply doubles as promotion.
- Free Resume Builder — unrelated but the same 1200×630 export pipeline lives under the hood if you are curious.
- Free Privacy Policy Generator — because the moment you start driving traffic from social, you need one.
FAQ
Do I need Open Graph tags if I already have Yoast SEO?
No — Yoast emits them automatically. This guide is for people who do not want Yoast.
What is the difference between Twitter Cards and Open Graph in 2026?
Open Graph is Facebook's protocol, adopted by LinkedIn, Slack, Discord, iMessage, WhatsApp, and most others. Twitter Cards are X-specific but fall back to OG if missing. Set both with the code above and you cover every major platform.
Why is my Facebook preview still showing the old image?
Facebook caches aggressively. Use the Sharing Debugger and click "Scrape Again" twice. If that fails, add ?v=2 to your image URL.
Can I add Open Graph tags to a specific WordPress page only?
Yes. Wrap the function body in if (is_page('slug')) or check get_the_ID() against a specific post ID.
What size should my og:image be?
1200×630 pixels, under 8MB, JPG or PNG. This is the Facebook-recommended spec and works everywhere else.
Does this work with Gutenberg / block themes / full-site editing?
Yes. The wp_head hook fires regardless of theme engine. Tested on WordPress 6.4 through 6.6.
Bottom Line
Adding Open Graph tags to WordPress is a 12-line code snippet, not a plugin install. Paste the code above, swap your default image URL, run the Facebook Debugger, and you are done. Your next social share will look like you hired a designer.
If you need a fast OG image to pair with the tags, generate one at ogtags.site — free, no signup, 1200×630 PNG in under 30 seconds.