WordPress 4.4 simplified the process of embedding WordPress content on other sites with the introduction of post embeds. From the feature’s announcement post:
WordPress has been operating as an oEmbed consumer for quite some time now, allowing users to easily embed content from other sites. Starting with version 4.4, WordPress becomes an oEmbed provider as well, allowing any oEmbed consumer to embed posts from WordPress sites.
As exciting as this feature is, it ran into an incompatibility with my server configuration. I’ve set the
X-Frame-Options header to
SAMEORIGIN near-universally within my nginx configuration, thereby blocking other sites from displaying my sites in frames; instead, my sites can only display their own content inside of frames. I’ve done so as a security measure against “clickjacking.” This header has no impact on my use of WordPress, nor on visitors’ interaction with my sites, but as I discovered, it breaks post embeds in an awkward way.
When another site tries to embed a post I’ve published, the
X-Frame-Options: SAMEORIGIN header tells the browser to check that the domain hosting the original content matches that of the site hosting the embed. If the domains don’t match, the browser refuses to load the embedded URL. As I reported in Trac ticket #35894, the embed failure causes WordPress to display a blank space without any relevant information about the embedded post.
WordPress 4.5 will improve how it handles this situation, but I was also curious if there were any configuration changes I could make to improve this experience.
The first suggestion came from Gary Pendergast, Core Contributor and fellow Automattician, via the aforementioned Trac ticket:
Side note that may be relevant to your interests (if you’d like to maintain the SAMEORIGIN restriction whilst allowing embeds) – URLs intended to embedded in an iframe include an
X-WP-embed: trueheader, which you can detect in nginx and remove the
X-Frame-Options: SAMEORIGINrule for that case.
I considered this approach, but quickly abandoned it as it requires significant modifications to my nginx configurations. Given how I’ve structured them (in part to ensure header consistency), the
X-Frame-Options header is set in several locations where I can’t use an
if statement to check for the
X-WP-embed header. Instead, I would need to use an nginx
map to specify a less-restrictive
X-Frame-Options header. Frankly, I don’t care enough about supporting embeds to bother with this level of changes.
A simpler solution
Next I looked at how WordPress generates the post-embed markup, quickly learning that I could exclude the unsupported
iframe with one line of code.
remove_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
Thanks to the above, WordPress returns the post embed as a simple title and link, rather than a rich snippet that will fail to load.
There is but one minor difference between the markup the above modification generates and what WordPress would otherwise produce as a fallback: the fallback is wrapped in a
blockquote tag. While I could add the
blockquote myself via the
oembed_response_data filter, again, I just don’t care enough; access logs reflect that I’m the only one requesting embeds, and that was just to test what I’ve written about here.