oEmbed Provider Generator
Paste a URL, get an embed. For services with a real oEmbed endpoint that is one line; for the ones without, this writes the regex handler instead.
<?php // Generated with WP CodeKit — powered by GrowQuest (https://growquest.io). /** * Plugin Name: Acme Video embeds * Description: Auto-embeds Acme Video URLs pasted into the editor. * Version: 1.0.0 * Requires PHP: 7.4 */ defined( 'ABSPATH' ) || exit; /** * Register the Acme Video oEmbed provider. * * WordPress appends ?url= and &format=json itself. */ function acme_register_provider() { wp_oembed_add_provider( 'https://video.example.com/watch/*', 'https://video.example.com/oembed', false // Whether the first argument is a regex. ); } add_action( 'init', 'acme_register_provider' ); /** * Cached embeds live in post meta and never expire on their own. * Run this once after changing the endpoint or the markup. */ function acme_flush_embed_cache() { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_oembed_%'" ); }
About this generator
oEmbed Provider Generator Online
Paste a URL, get an embed. For a service that publishes an oEmbed endpoint that is a single wp_oembed_add_provider() call, and this generator writes it with the pattern, the endpoint and the regex flag in the right order. For a service with no endpoint at all, it switches to wp_embed_register_handler() and builds the regex, the iframe and a responsive wrapper instead.
A live pattern tester sits in the form: paste a real URL from the service and it tells you whether the wildcard pattern matches and what it captured, before you paste anything into a site. Free, no account, and nothing is sent anywhere.
Reviewed Output tested on WordPress 6.8 · PHP 8.3
Why the wp_oembed_add_provider generator beats a one-line snippet
The registration is trivial. What costs time is everything around it: a pattern with no wildcard that matches exactly one URL, an http:// pattern that never matches the https:// URLs people actually paste, an endpoint with ?url= already in it that WordPress then appends to, and embeds cached in post meta that keep showing the old markup long after you fixed the code.
Provider or handler, from the same form
A provider is one call and always renders whatever the service returns. A handler is your own regex and your own iframe, needed when the service publishes no endpoint — and permanently your maintenance problem when their embed URL changes. The generator explains which you are choosing and writes either.
A live pattern tester
Paste a real URL from the service and the form reports whether the pattern matches and which id was captured. A test URL that does not match raises a warning with the reason, so you never register a pattern that quietly matches nothing.
Endpoint mistakes caught first
An endpoint that already contains url= or format= is an error with a one-click strip, because WordPress appends both itself and the resulting request is malformed. Insecure endpoints are rejected, and a pattern with no wildcard, a double wildcard or an http:// scheme each gets its own warning and fix.
Handler markup that behaves on a phone
The generated iframe carries loading="lazy", a translated title attribute built from the captured id, optional allowfullscreen, and a responsive wrapper using the padding trick for a 16:9, 4:3, 1:1 or 9:16 ratio. Without the wrapper an embed keeps whatever fixed size you gave it and overflows on narrow screens.
The caching problem, addressed
Successful embeds are cached in post meta under _oembed_ keys and never expire on their own, so the generator can include the one-off cleanup query you run after changing an endpoint or the markup. The oembed_ttl filter is offered separately, with the note that it only governs how long a failed lookup is remembered.
Honest advice about the extras
Adding your host to allowed_redirect_hosts is offered, and immediately flagged: it has nothing to do with embedding and widens what wp_safe_redirect() will follow. Providers get a reminder that if the endpoint 404s the URL degrades to a plain link, which is a much better failure than a broken iframe.
How does the oEmbed Provider Generator work?
Four steps, and the pattern is tested against a real URL before you leave the page.
- 01
Pick provider or handler
Check the service documentation for an
/oembedendpoint or a.well-knownentry first. If it has one, choose provider. If it genuinely has none, choose handler. - 02
Describe the URL
Give the service a name, a function prefix and the URL pattern people paste, using
*where the id varies. Add the oEmbed endpoint for a provider, or the iframe URL template with%1$sfor a handler. - 03
Test and tune
Paste a real URL into the test field and confirm the capture. For handlers, set the aspect ratio, the responsive wrapper and fullscreen; for either, decide whether to include the cache-flush routine or an
oembed_ttlfilter. - 04
Export as a plugin
Clear the Checks tab and take the plugin output. Embeds usually outlive the design, and a URL that stops embedding after a theme switch is a confusing bug to chase.
Worked example — registering a provider and clearing stale embeds
One registration on init, plus the one-off cleanup you run after changing the endpoint. Note that the endpoint has no query string: WordPress appends ?url= and &format=json itself.
/**
* Register the Acme Video oEmbed provider.
*
* WordPress appends ?url= and &format=json itself.
*/
function acme_register_provider() {
wp_oembed_add_provider(
'https://video.example.com/watch/*',
'https://video.example.com/oembed',
false // Whether the first argument is a regex.
);
}
add_action( 'init', 'acme_register_provider' );
/**
* Cached embeds live in post meta and never expire on their own.
* Run this once after changing the endpoint or the markup.
*/
function acme_flush_embed_cache() {
global $wpdb;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_oembed_%'" );
}The third argument tells WordPress whether the first one is a full regex. Left as false, the pattern is a glob and each * is expanded internally, which is what you want for a URL shape like /watch/{id}.
oEmbed providers & handlers — frequently asked questions
The questions that come up when a pasted URL does not turn into an embed.
How do I add a custom oEmbed provider in WordPress?
Call wp_oembed_add_provider( $pattern, $endpoint, $is_regex ) from a callback on init, passing the URL shape users paste (with * wildcards), the service's oEmbed endpoint and false unless your pattern is a full regex. Never put ?url= or &format=json in the endpoint — WordPress adds both when it makes the request.
Why does my URL show as a plain link instead of an embed?
Auto-embedding only happens when the URL is alone on its own line or in its own paragraph or Embed block; a URL inside a sentence is left as text. Beyond that: the provider may not be registered by the time the content renders, the endpoint may be returning an error (in which case WordPress deliberately falls back to a link), or an old result may be cached against that post.
What do I do when a service has no oEmbed endpoint?
Use wp_embed_register_handler() instead. You supply a unique id, a full PCRE pattern with delimiters and a callback that receives the regex matches, the attributes and the original URL, and returns the markup. You are then responsible for the iframe, its sizing and its privacy attributes forever — so check the service's documentation for an endpoint before committing to this.
How do I clear the WordPress oEmbed cache?
Successful responses are stored as post meta with keys beginning _oembed_, and they do not expire. Deleting those meta rows forces WordPress to fetch again the next time the post is rendered. Until you do, a post keeps showing the markup that was returned when it was first saved, which is why changing an endpoint appears to have no effect on old content.
Can I change the markup a provider returns?
Yes, with filters rather than by changing the provider. oembed_result receives the raw HTML the service returned, and embed_oembed_html receives the final HTML just before it is printed — that is the usual place to wrap an embed in a responsive container or strip an attribute. Neither changes what is cached unless you clear the existing _oembed_ meta.
Do I need to register a provider at all?
Often not. Core ships a list of supported services and, for URLs it does not recognise, it can discover an endpoint from the page's own link rel="alternate" oEmbed tag. Registering explicitly is what you do when the service publishes an endpoint but no discovery link, when you want to avoid the extra discovery request, or when you are replacing one of core's providers — for which wp_oembed_remove_provider() comes first.
Where do I paste the code from the oEmbed Provider generator?
You have three good options and one bad one. Best is a small site-specific plugin — the generator can output one for you, and it keeps working when you change theme. A code-snippets plugin is fine too. A child theme's functions.php works but ties the code to that theme. Never edit the parent theme: the next update overwrites it and your code is gone.
Can I use the generated code in client work or a commercial plugin?
Yes. The output is ordinary WordPress API calls that you configured — there is no licence attached to it and no attribution required. Use it in client sites, commercial plugins and themes, or products you sell. The generated file carries a short credit comment you are free to delete.
The other Core generators in the library, plus the WordPress tools most often used alongside this one.