WordPress External Featured Image via cURL

Ciprian on Friday, May 14, 2021 in Blog

WordPress External Featured Image

Here’s the long title for this code snippet —

How to set up an external image as a WordPress featured image and inject it into header as an og:image meta tag, suitable for LinkedIn and Facebook

Why did I do this? Because Yoast SEO does not add an og:image tag automatically, if there is no locally hosted featured image. I also did it because in this very specific case, my images were served from a script and generated on the fly based on width, height, quality and cropping URL parameters. Here’s my workaround:

/**
 * Use external URL for featured image (helps with social sharing)
 * 
 * Get the cURL effective URL and save it in a custom meta field.
 * Output custom Open Graph meta tags based on the saved URL.
 */
function whiskey_thumbnail_external_replace() {
    global $post;

    if (empty($post->ID) || (string) get_post_type($post->ID) !== 'custom-post-type') {
        return;
    } else {
        if ((string) get_post_meta($post->ID, '_whiskey_featured_image', true) === '') {
            $url = 'path/to/image/;

            // Use cURL to get the image path if it doesn't exist
            $curl = curl_init();
            curl_setopt_array($curl, [
                CURLOPT_URL => $url,
                CURLOPT_HEADER => true,
                CURLOPT_NOBODY => true,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_CUSTOMREQUEST => 'GET',
                CURLOPT_ENCODING => ''
            ]);
            $response = curl_exec($curl);
            $redir = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
            curl_close($curl);
            //

            $url = $redir;

            update_post_meta($post->ID, '_whiskey_featured_image', $url);
        } else {
            $url = get_post_meta($post->ID, '_whiskey_featured_image', true);
        }

        if ((string) $url !== '') {
            add_filter('wpseo_frontend_presenter_classes', 'whiskey_wpseo_frontend_presenters', 10, 1);

            // LinkedIn
            echo '<meta name="image" property="og:image" content="' . $url . '">';

            // Facebook
            echo '<meta property="og:image" content="' . $url . '">';
            echo '<meta property="og:image:alt" content="' . get_the_title($post->ID) . '">';

            if (getimagesize($url)) {
                $size = getimagesize($url);

                echo '<meta property="og:image:width" content="' . $size[0] . '">
                <meta property="og:image:height" content="' . $size[1] . '">';
            }
        }
    }
}

function whiskey_wpseo_frontend_presenters($presenters) {
    if ($matches = preg_grep('/Image_Presenter/', $presenters)) {
        return array_diff($presenters, $matches);
    } else {
        return $presenters;
    }
}

add_action('wp_head', 'whiskey_thumbnail_external_replace', -1000);

Note that I am storing the final URL in a custom meta field and I am using CURLINFO_EFFECTIVE_URL to get the last effective URL (after all redirects). Also note that you need CURLOPT_FOLLOWLOCATION to be set to true.

After I get the image, I am adding 5 meta tags (one for LinkedIn and 4 for Facebook). Here they are:

<!-- LinkedIn -->
<meta name="image" property="og:image" content="/path/to/image/">

<!-- Facebook -->
<meta property="og:image" content="/path/to/image/">
<meta property="og:image:alt" content="This is the title">
<meta property="og:image:width" content="1920">
<meta property="og:image:height" content="1080">

If you are using an SEO plugin other than Yoast’s, you might not need this workaround.

Photo by Eric Park on Unsplash.

Related posts

2 comments on “WordPress External Featured Image via cURL

  1. you could also use the wordpress http api, and add from external url to media library and set as thumbnail as well

    1. True, but the idea was to not save anything locally. In my specific case, these images would expire and change, so I need the featured image to be dynamic.

Leave a Reply

Your email address will not be published. Required fields are marked *