Twitter の埋め込み用スクリプトを拾ってくるやつ
#tech
SPA じゃない場合はどうやってもブラウザのキャッシュ頼みになる気がする……
Twitter は @types/twitter-for-web で生えるやつ(widgets とか createTweet() にも型がつく)
code:ts
import { useEffect, useState, useMemo } from 'react'
/**
* 必要なら twitter の widgets.js をロードし、window.twttr.widgets を返す
*
* @example
* const widgets = useTwitterWidgets()
* useEffect(() => {
* ref.current && widgets?.createTweet('xxxxxxxxxx', ref.current, { conversation: 'none' })
* }, widgets)
*
* @see https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/set-up-twitter-for-websites
*/
export function useTwitterWidgets() {
// !!(window.twttr as Twitter)?.widgets のほうが安全……?
const isLoaded, setIsLoaded = useState('widgets' in (window.twttr || {}))
const widgets = useMemo(() => (isLoaded ? (window.twttr as Twitter).widgets : null), isLoaded)
useEffect(() => {
if (!isLoaded) {
const script = document.createElement('script')
script.async = true // いらないかも……?
script.src = 'https://platform.twitter.com/widgets.js'
script.addEventListener('load', () => window.twttr.ready(setIsLoaded(true)))
document.body.appendChild(script)
return () => void document.body.removeChild(script)
}
}, isLoaded)
return widgets
}
createTweet() の呼び方に関して、useLayoutEffect() で呼んだり await したりしなくていいの?という疑問はあるけど、zenn の人の記事とか野良ライブラリの実装では useEffect() でやっており、自分の環境でもそれで問題なさそうだった
参考 URL
https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/set-up-twitter-for-websites
https://developer.twitter.com/en/docs/twitter-for-websites/embedded-tweets/guides/embedded-tweet-javascript-factory-function
https://developer.mozilla.org/ja/docs/Web/API/HTMLScriptElement#スクリプトの動的なインポート
https://zenn.dev/catnose99/articles/329d7d61968efb
https://github.com/saurabhnemade/react-twitter-embed/blob/4.0.5/src/components/TwitterTweetEmbed.tsx