WordPress Media Iframe With Custom Attributes

I recently worked on a case in the WordPress block editor in which I needed to add support for clipboard events in a media iframe. In this case, the iframe was being used inside a custom version of wp.media.view.MediaFrame. While wp.media.view does not natively support custom attributes on iframes, we can create our own custom media iframe with custom attributes.

If you have a WordPress installation up and running, you can find the code for wp.media.view.Iframe in wp-includes/js/media-views.js. It should look like the following:

/**
 * wp.media.view.Iframe
 *
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
var Iframe = wp.media.View.extend(/** @lends wp.media.view.Iframe.prototype */{
	className: 'media-iframe',
	/**
	 * @return {wp.media.view.Iframe} Returns itself to allow chaining.
	 */
	render: function() {
		this.views.detach();
		this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" />' );
		this.views.render();
		return this;
	}
});

module.exports = Iframe;

I’ll admit I don’t love the implementation of iframes that we see above. Using jQuery to set the HTML of a WP core element while providing no filtering options seems less than friendly to developers.

For the specific task of adding support for clipboard-write events I created a custom iframe implementation that is a near-duplicate of the WP core version, but renamed and with allow="clipboard-write" included as an attribute of the iframe element:

/**
 * wp.media.view.ClipboardWriteIframe
 * A custom version of wp.media.view.Iframe,
 * adding support for clipboard-write events
 * 
 * @memberOf wp.media.view
 *
 * @class
 * @augments wp.media.View
 * @augments wp.Backbone.View
 * @augments Backbone.View
 */
 var ClipboardWriteIframe = wp.media.View.extend(/** @lends wp.media.view.ClipboardWriteIframe.prototype */{
	className: 'media-iframe',
	/**
	 * @return {wp.media.view.ClipboardWriteIframe} Returns itself to allow chaining.
	 */
	render: function() {
		this.views.detach();
		this.$el.html( '<iframe src="' + this.controller.state().get('src') + '" allow="clipboard-write"/>' );
		this.views.render();
		return this;
	}
});

module.exports = ClipboardWriteIframe;

In the file where my custom wp.media.view.MediaFrame exists, I found the iframeContent method:

/**
* @param {Object} content
* @this wp.media.controller.Region
*/
iframeContent: function( content ) {
	this.$el.addClass('hide-toolbar');
	content.view = new wp.media.view.Iframe({
		controller: this
	});
},

Then I changed the method to use my custom ClipboardWriteIframe class:

/**
* @param {Object} content
* @this wp.media.controller.Region
*/
iframeContent: function( content ) {
	this.$el.addClass('hide-toolbar');
	content.view = new ClipboardWriteIframe({
		controller: this
	});
},

While this was a fairly straightforward modification to make, it’s easy to see how one could further customize the attributes on a media iframe. In this implementation, we can add any static HTML attributes to the iframe element by simply hardcoding them in the iframe as I’ve done above with allow="clipboard-write". We could also add dynamic attributes similarly to how the src attribute gets applied. For example, if we have an id value held in state and we’d like to apply this to the iframe element, our changed line of code might look like the following:

this.$el.html('<iframe src="' + this.controller.state().get('src') + '"' + 'id="' + this.controller.state().get('id') + '"/>');

Typically I would avoid cloning and modifying WordPress core functionality. However, in this case it proved to be the best way of achieving a media iframe with custom attributes.

the author profile picture

Ryan Neilson is a software developer from Nova Scotia, Canada, where he lives with his wife and their menagerie of pets. He has worked extensively with PHP, WordPress, JavaScript, React, SCSS and CSS. Ryan can be found professionally at News Corp, where he works as a lead software engineer.