# OG images in WordPress

Generate on publish, store the URL in post meta.

## Where it plugs in

In WordPress you do not want to hit the API on every page view. Hook into the post save, generate once, and store the URL in a meta field that your theme or SEO plugin reads later.

`functions.php`

```php
add_action('save_post_post', function (int $post_id, WP_Post $post): void {
    if (wp_is_post_revision($post_id) || $post->post_status !== 'publish') {
        return;
    }

    $response = wp_remote_post('https://shareglint.com/v1/images?wait=true', [
        'timeout' => 15,
        'headers' => [
            'Authorization' => 'Bearer ' . SHAREGLINT_KEY,
            'Content-Type'  => 'application/json',
        ],
        'body' => wp_json_encode([
            'template' => 'blog-og',
            'modifications' => [
                'title'  => get_the_title($post),
                'author' => get_the_author_meta('display_name', $post->post_author),
                'site'   => wp_parse_url(home_url(), PHP_URL_HOST),
            ],
        ]),
    ]);

    if (is_wp_error($response)) {
        return;
    }

    $body = json_decode(wp_remote_retrieve_body($response), true);

    if (! empty($body['url'])) {
        update_post_meta($post_id, '_og_image', esc_url_raw($body['url']));
    }
}, 10, 2);

// Print it in <head> if you are not using an SEO plugin.
add_action('wp_head', function (): void {
    if (! is_singular('post')) {
        return;
    }

    $image = get_post_meta(get_the_ID(), '_og_image', true);

    if ($image) {
        printf('<meta property="og:image" content="%s">' . "\n", esc_attr($image));
        echo '<meta name="twitter:card" content="summary_large_image">' . "\n";
    }
});
```

## The trap

The `save_post` hook also fires on autosaves and on every update. The `post_status` and `wp_is_post_revision` guards are what stop you from generating a dozen images while writing a single post.

## What it costs

A hundred images a month free, then $9 for two thousand. The same post rendered twice returns the existing URL and uses no quota — so rebuilding your site costs nothing.
