On a recent project we had a requirement to let users easily include social media such as YouTube videos, and Instagram posts in their content. We choose to follow the WordPress-embed style functionality where simply including a link to the social media in the post would embed it using oEmbed discovery.
oEmbed allows a service (such as YouTube, or Instagram) to be queried in a standard way, and to return markup representing the resource. Embedding a YouTube video this way does what you’d expect – an embed of the video. Embedding Instagram embeds the image in an Instagram frame.

Before…

After…
In WordPress, all of this happens without the content author having to do anything complex – just paste in the URL of the content they want to embed into their post, and WordPress does the rest. We wanted to reproduce those features, and ease of use in our project, which isn’t WordPress, but based on the Laravel framework.
There are however plenty of libraries that you can use to do the heavy lifting – particularly embed/embed:
Get info from any web service or page
https://github.com/php-embed/Embed
316 forks.
2,123 stars.
70 open issues.
Recent commits:
- Merge pull request #562 from uzulla/use-phpstanAdd PHPStan Static Analysis (Level Max + Strict Rules), GitHub
- Ignoring argument type, VĂtor de Oliveira
- fix: add trim() to adapter detectors for consistent whitespace handlingUpdate all adapter detector classes to use trim() when checking for emptystrings, ensuring whitespace-only strings properly fall back to parentdetectors. This aligns adapter detectors with the pattern used in basedetector classes.Changes:- Twitter: AuthorName, Description- Wikipedia: Title, Description- Archive: Title, AuthorName, Description- ImageShack: Title, AuthorName, Description- Gist: AuthorName, uzulla
- fix: add unit tests for AuthorUrl detectors handling empty and zero strings, uzulla
- fix: ensure empty strings fallback to next metadata source in detectorsPreviously, detectors would return empty strings from primary sources (likeoembed) without falling back to alternative sources (like metas), losingvaluable metadata. Now empty and whitespace-only strings are treated asmissing data, triggering the fallback chain.Problem:When oembed or other primary sources returned empty strings instead of null,detectors would return those empty values immediately, preventing fallbackto metas, linked data, or document sources that might contain valid data.Solution:Add empty string validation using trim() to ensure fallback chain executesproperly: if (is_string($result) && trim($result) !== '')Impact:- AuthorName: Empty oembed author_name now falls back to metas- Title: Empty oembed/metas titles now fall back to document <title>- Description: Empty oembed/metas descriptions fall back to linked data- ProviderName: Empty oembed/metas names fall back to hostname- Language: Empty html lang attributes fall back to meta tagsThis improves metadata extraction quality by utilizing all available sourcesinstead of stopping at the first non-null but empty response., uzulla
This lets you simply pass in a URL and get back all sorts of information, including the title, image, and embed code so you can use it how you like. This allowed us to get a proof of concept up and running in our project pretty quickly. However – everything was being embedded in realtime, with oEmbed calls being made to embed resources every time we loaded a page.
To solve this, we created a bridge between Laravel’s cache system and the embed library such that we can load an embed once, and cache the embed code produced, and just re-use that, decreasing load on external services, and increasing load times.
Usage, is simple you just use it as you would embed/embed. If the data is in the cache it will come from there, otherwise it will be fetched and cached automatically.
Happy embedding!