Headless WordPress: OG images on publish
No plugin to install, no marketplace review: a mu-plugin (one PHP file in wp-content/mu-plugins/) calls the OGImagen API when a post is published and stores the permanent image URL in post meta. Your Next.js / Astro frontend reads it over REST or WPGraphQL.
1. The mu-plugin
<?php
/**
* Plugin Name: OGImagen on publish
* Drop into wp-content/mu-plugins/ogimagen.php
* Define OGIMAGEN_API_KEY (and optionally OGIMAGEN_BRAND_KIT_ID) in wp-config.php.
*/
add_action('transition_post_status', function ($new, $old, $post) {
if ($new !== 'publish' || $post->post_type !== 'post') return;
if (get_post_meta($post->ID, 'ogimagen_url', true)) return; // already done
$res = wp_remote_post('https://ogimagen.com/api/v1/templates', [
'timeout' => 20,
'headers' => [
'Authorization' => 'Bearer ' . OGIMAGEN_API_KEY,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode([
'template' => 'blog',
'title' => get_the_title($post),
'siteName' => wp_parse_url(home_url(), PHP_URL_HOST),
'brandKitId' => defined('OGIMAGEN_BRAND_KIT_ID') ? OGIMAGEN_BRAND_KIT_ID : null,
]),
]);
if (is_wp_error($res)) return;
$data = json_decode(wp_remote_retrieve_body($res), true);
if (!empty($data['url'])) {
update_post_meta($post->ID, 'ogimagen_url', esc_url_raw($data['url']));
}
}, 10, 3);
// Expose the meta field to REST + WPGraphQL consumers.
add_action('init', function () {
register_post_meta('post', 'ogimagen_url', [
'show_in_rest' => true,
'single' => true,
'type' => 'string',
]);
});That's the whole integration for the template path: synchronous, deterministic, zero credits, every post carries the same branded layout.
2. Read it from the frontend
// Next.js App Router
export async function generateMetadata({ params }) {
const post = await fetch(
`${WP_URL}/wp-json/wp/v2/posts?slug=${params.slug}`
).then((r) => r.json()).then((p) => p[0]);
return {
openGraph: {
images: post.meta?.ogimagen_url ? [post.meta.ogimagen_url] : [],
},
};
}Using Yoast alongside? Write the same URL into _yoast_wpseo_opengraph-image and Yoast's yoast_head output picks it up, no frontend change needed.
3. Optional: AI for hero posts
Swap the endpoint for /api/v1/generations on posts with a custom field flag. AI is async, so pass webhookUrl pointing at a tiny REST route (or a serverless function) that runs update_post_meta when the generation.completed event arrives, payload and signature details in the API docs. Include an idempotencyKey (hash of slug + title) so republishing never double-charges.
Classic (non-headless) WordPress?
The same mu-plugin works on a classic theme, Yoast/Rank Math will output the meta tag for you. If you'd rather not touch PHP at all, the n8n/Make recipe drives WordPress over its REST API with zero code on the server.
Full parameter reference in the API docs. Other platforms: all recipes.