WordPress oEmbed is a really cool feature, which allows you to embed media from a supported oEmbed provider simply by adding the URL to that media on a line of its own. If you already understand oEmbed as a user, skip a head to the section How WordPress oEmbeds Work.
For example, if you put the following on its own line in WordPress
WordPress automatically replaces this with the actual video.
WordPress oEmbed in the Text Editor
WordPress Rendered oEmbed in the WYSIWYG Editor
If you add one of these oEmbed URLs when you’re using the WYSIWYG editor, you’ll see the video appear right within your editor.
Which Media Sites Can I Use for oEmbeds?
How WordPress oEmbeds Work
WordPress analyzes the URL (e.g.
https://www.youtube.com/watch?v=cSj-etJL3nI) to determine, which supported media provider it came from (in this case YouTube) and then makes an API call to the URL that corresponds to that provider (in the case of YouTube, calls are made to
http://www.youtube.com/oembed) with additional parameters like what piece of media you want.
In the case of the example above, WordPress calls https://www.youtube.com/oembed?maxwidth=500&maxheight=750&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DcSj-etJL3nI&format=json and uses that information to create the markup to embed the video.
WordPress Caches oEmbed Results
Adding a call to a remote URL every time you load a page is a bad idea and will slow down your page significantly. The good news is WordPress has you covered and stores the resulting markup in post meta so the API call doesn’t have to occur each time.
You may be asking, “Why store the resulting markup as post meta? Wouldn’t a transient make more sense?” Post meta was chosen because the oEmbed markup should never be deleted based on being expired. If the markup is over one day old and the page is loaded on the backend, then the markup is updated (but if the lookup fails, the last good markup is not replaced). The markup is never updated when the page is loaded on the front-end. This behavior differs greatly from a transient, which expires and gets deleted automatically. See Mark Jaquith’s notes on how oEmbed caching works.
oEmbed Outside the Editor
Sometimes you want to embed media outside the editor (e.g. I recently did this because the content was displayed in multiple columns with CSS but the video appeared at the end and spanned all the columns). In this case, the media URL can be stored as a post meta value and the media URL can be programmatically changed into the markup for embedding.
Do NOT Use wp_oembed_get() without Caching
I’ve seen a lot of recommendations online to use
wp_oembed_get() in this situation. Using
wp_oembed_get() will make the call to the correct provider endpoint and render the proper markup to add the media to your page, however it will not cache the result. This means that every time your page attempts to load, WordPress will make an HTTP request to the media provider, which will prevent the page loading until the result is returned.
You can see the HTTP call being made each time the page loads if you run the Query Monitor plugin. You do not want to make an HTTP call every time your page loads.
How to Cache oEmbeds
Single Pages or Posts
If you are going to be displaying the video in a way that there is a single post ID associated with it, which should be the case if you’re using post meta to store the URL, you can use the __global__
global $wp_embed; $video_url = 'https://youtu.be/cSj-etJL3nI'; echo $wp_embed->shortcode( array(), $video_url );
Not on a Single Page or Posts
If you are loading an oEmbed video in an area where there is not a single post ID associated with it (e.g. in the header, footer, archive page, search results page, or 404 page) you’ll need to cache the result yourself. How this is handled will have a lot to do with where the video URL is coming from.
I imagine the most likely scenario is you’re storing it in a WordPress database option, in which case I’d probably add some code when the option is saved that makes the
wp_oembed_get() call and stores the result in another option. I haven’t actually had this come up on any of my projects (but hopefully these notes will help me if I do).
Image Modified from original by Cory Doctorow