見出し画像

ReactでinstagramのEmbed

ショッピングサイトの制作をしているなかで、商品の詳細ページにinstagramの投稿を挿入したいという事案がありました。

一般的に考えると、instgramの投稿から「埋め込み」のHTMLをコピーしてきて、HTMLに貼り付ければ、投稿の埋め込みができます。noteではURLを貼り付けると投稿が埋め込みできるようになっています。

今回制作しているECサイトは、フロント側をReactで記述しているため、「埋め込み」でコピーしたコードを貼り付けるだけでは、正常に動かなそうです。

まず解決策として、react-instagram-embed で埋め込むということを考えました。

<InstagramEmbed
 url='https://instagr.am/p/Zw9o4/'
 maxWidth={320}
 hideCaption={false}
 containerTagName='div'
 protocol=''
 injectScript
 onLoading={() => {}}
 onSuccess={() => {}}
 onAfterRender={() => {}}
 onFailure={() => {}}
/>

ただ、この場合、本文中に埋め込むためには、「埋め込み」用のコードを解析してURLを抜き出すか、登録時にURLのみを登録させるようなデータの持ち方をする必要がでてきます。

今回バックエンドは、APIを呼び出す形で制作しているます。本文中に埋め込むHTMLについては、Reactではない言語で書かれたデバイスでも同じように表示されるように、特殊な形式にはしたくないという事情があります。

そのような事情で、今回はreact-instagram-embedは使用できないので、他の方法を考えることになりました。

そもそも、なぜReactでうまく動かないか、ということを考えるために埋め込みコードをみてみると、

 <script async src="//www.instagram.com/embed.js"></script>

コードの一番最後に、このようなコードがあることがわかります。Reactではここにあるscriptファイルは読めないので、まず、このJavascrip自体は一旦、index.htmlで事前に呼んでおくことにしました。

一般的なHTMLで埋め込みした場合は、このJavascriptファイル内にある

instgrm.Embeds.process()

が実行されて、写真が表示される仕組みになっているようです。

Reactの場合、Stateが更新されると、毎回viewについては再描画されるため、一度このprocessを呼んだだけでは、stateが更新されると表示されなくなってしまいます。

ということで、結果的にstateが更新されるたびにこのprocessを呼ぶことにして解決することができました。

componentDidUpdate(){
   if (window.instgrm) {
       window.instgrm.Embeds.process()
   }
 }

これでBlogのようなエントリーツールで書かれたHTMLにEmbedされた、instagramの投稿を表示できるようになりました。

embed用のJavascriptファイルをindex.htmlで呼んでしまっていますが、必要ない時も毎回呼ぶことになるので、ここは必要な時だけ呼べるような仕組みにするという課題は残っています。


この記事が気に入ったらサポートをしてみませんか?