Use Iframely embeds with ReactJS

Known issue

React has its own virtual DOM. Hence it does not execute the inline scripts that go with the HTML elements you add. Even when you use dangerouslySetInnerHTML. Even if that "dangerous" HTML is actually fairly safe. React considers that you expose youself to the risks of out-of-sync virtual DOM.

This said, ReactJS can not support any JavaScript-based embeds out-of-the-box. It means you need a workaround for, say, Twitter, Instagram, Imgur, GitHub Gists, Iframely cards and lazy-loaded iFrames, and, well, Facebook itself.

All iFrame-based embeds are absolutely fine and cause no DOM issues.

We do not have a bullet-proof fix for you in general case, if you use native embed codes from publishers as-is. However, if you opt to rely on Iframely's smart iFrames, this guide will make all embeds work for you.

The solution

The fix is fairly simple: Iframely offers a single external embed.js script that you need to deal with. It is served from our global CDN and is attached to all embeds that require scripting.

You may actually show all embeds just with embed.js by simply marking up your links as <a href='...' data-iframely-url></a>.

However, with dynamic React-powered pages, the initial load may be a little jerky that way, and so we also suggest iFrame-based approach as well. Read on.

Add embed.js to your page

In a simple form, it is just

<script src="//cdn.iframe.ly/embed.js" async></script>

See this gist if you'd rather conditionally add embed.js only when there are embeds on your page that need it.

Omit script

With your API calls, add &iframe=true and &omit_script=true as query-string parameters. This will tell Iframely that you load embed.js script yourself. API will therefore return direct iFrame with proper attributes and wrapping divs instead of universal <a> embed.

Your React component

Add following methods to your React component:

componentDidMount: function() {
    // This is required if you use pure embed.js approach
    // Or if you use lazy-loading of iFrames
    // It initiates the iFrame and adjusts its height if required
    window.iframely && iframely.load();
},

// Depending on your components, you may need to move iframely.load() 
// from `componentDidMount` to `componentDidUpdate`. Quote from React docs:
// "Do note that componentDidMount will however not be called on component updates"

getIframelyHtml: function() {
    // If you use embed code from API
    return {__html: this.iframelyEmbedHtmlCode};

    // Alternatively, if you use plain embed.js approach without API calls:
    // return {__html: '<a href="' + this.url + '" data-iframely-url></a>'}; 
    // no title inside <a> eliminates the flick
},

render: function () {
    // Don't get scared away by `dangerouslySetInnerHTML` :)
    return <div dangerouslySetInnerHTML={this.getIframelyHtml()} />
}