WordPress 5.3.x YouTube oEmbed is not working

We followed Brian Fegter’s answer to display YouTube videos using WordPress’ oEmbed feature:

// Public video.

require_once(ABSPATH . 'wp-includes/class-wp-oembed.php');
$oembed = new WP_oEmbed;

// Auto-detect the video provider with the following
$provider = $oembed->discover($video_url);

$video = $oembed->fetch($provider, $video_url);

echo $video->html;

The code worked earlier. But right now it’s not working. We’re using WordPress 5.3.2. We tried updating WordPress to 5.3.6, but no luck.

The main issue is: $oEmbed->discover() cannot detect any provider and returning false. 🙁

You can see the issue live at this link. (For some time, we’re showing some of the debug information, if you need them)

Debug information

1 Answer

So apparently the issue also happens in WordPress 5.6 (the latest release as of writing), and YouTube is probably at fault because the (oEmbed) <link> tags are in the body instead of the head (see screenshot below), and that in turn causes the issue because WP_oEmbed::discover() looks for the <link> tags in the head only. And secondly, YouTube uses http:// instead of https:// (secure protocol) in the <link> tags, so you would need to replace that http:// with https:// if your site uses https:// or is SSL-enabled.

Screenshot 1: Elements inspector tab (in Chrome)

Chrome DevTools

Screenshot 2: Server-generated HTML source (press Ctrl+U on Chrome)

Chrome view-source

And maybe (YouTube is not at fault and) the WordPress core team should revise the function so that it tries to also search in the body? Or perhaps use a better way to find the tags like using DOMDocument …?

But anyway, as mentioned by @Rup, you could alternatively use WP_oEmbed::get_provider() which will load the sanctioned/trusted oEmbed providers defined in the class constructor, and (as of writing) YouTube is actually the very first in the providers list.

// So instead of:
// this fetches the <link> tags from the provider site
$provider = $oembed->discover( $video_url );

// Use this one:
// this finds in the sanctioned oEmbed providers first
// then tries with the above discover()..
$provider = $oembed->get_provider( $video_url );

Or as I said in the comments, if you just wanted to get the HTML/embed code, then you could simply use wp_oembed_get() which should work since, although indirectly, the function uses WP_oEmbed::get_data() which uses WP_oEmbed::get_provider():

// I'd prefer this:
echo wp_oembed_get( $video_url );

// But that is equivalent to:
$video = $oembed->get_data( $video_url );
echo $video->html;

// And that is equivalent to:
$provider = $oembed->get_provider( $video_url );
$video = $oembed->fetch( $provider, $video_url );
echo $video->html;

Leave a Comment