SNSボタンをReactのサイトに埋め込む

July 17, 2019

LPなんか作るときにこういったSNSボタンを埋め込むことがあります。ただReactのサイトで埋め込もうと思ったらReactのライフサイクル上でscriptの読み込みなどを発生させる必要があるので、少し面倒なところがあります。

LINEの友だち追加ボタンの埋め込みコードは↓ここから取得できます。

LINE Social Plugins

今回はこのボタンを埋め込みます。

          2019 07 18 7 47 43

埋め込みコードはこんな感じ。scriptタグがあるので、div要素がちゃんとマウントされた状態でscirptを読み込む必要があります。

<div class="line-it-button" data-lang="ja" data-type="friend" data-lineid="@lineteamjp" style="display: none;"></div>
<script src="https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js" async="async" defer="defer"></script>

Helmetを使ってみた

React HelmetはReactでheadタグが記述できるライブラリです。

GitHub - nfl/react-helmet: A document head manager for React

<Helmet>
  <script src="https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js" />
</Helmet>

これだとdiv要素のマウント後に読み込まれるかどうかが担保されないかもしれないのでまずそうです。

scriptタグを読み込ませる

結局、useEffectを使った方法でscriptを読み込ませることにしました。wrapperはボタンを囲う親要素のrefです。

useEffectの第二引数を[]にするとComponentDidMount相当の挙動になるのでdiv要素のマウントが担保されます。

const wrapper = useRef(null);
useEffect(() => {
  const script = document.createElement("script");
  script.src =
    "https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js";
  script.async = true;
  script.defer = true;
  (wrapper.current as any).appendChild(script);
}, []);

SPAに対応させる

これだと他のページで同じコンポーネントを使っている場合、ページ遷移したときにscript内の関数が呼ばれないのでボタンが正しく表示できません。

結局、scriptのコードを読んで呼び出している関数を呼ぶという泥臭い感じで実装しました。

const wrapper = useRef(null);
useEffect(() => {
  const win = window as any;
  if (win.LineIt) {
    win.LineIt.loadButton();
  } else {
    const script = document.createElement("script");
    script.src =
      "https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js";
    script.async = true;
    script.defer = true;
    (wrapper.current as any).appendChild(script);
  }
}, []);