Nuxt(Vue)でツイートを埋め込みたい(埋め込みウィジェット, vue-tweet-embed)


この記事は「株式会社オープンストリーム "小ネタ" Advent Calendar 2020」の 17 日目の記事です。

以前、Nuxt(Vue)に Twitter のツイートを埋め込むときは vue-tweet-embed のパッケージを使うとよさそうと考えましたが、 うまくいかないときがあったので諦めてました。

確かめる機会ができたのでここにまとめます。

環境

  • Nuxt.js 2.14.9
  • Storybook 6.0.10
$ node -v
v14.5.0

$ yarn -v
1.22.5

通常通りツイートを埋め込む

Twitter のコードを使ってツイートを埋め込むときは次の 2 つの情報が必要になります。

  • screen_name
  • tweet の id

DB のテーブルに id しか保存していない場合は、別のテーブルから screen_name を持ってこなければならないので厄介です。

また、埋め込み用コードのほかに https://platform.twitter.com/widgets.js のスクリプトを読み込む必要があり、読み込む位置によって SPA でページ遷移した後の挙動がおかしくなるなど注意が必要です。

私もスクリプトをねじ込んでツイートを埋め込みましたが、こちらのコードのほうが SPA でのページ遷移が考慮されているため紹介します。

Nuxt.js で Twitter シェアボタンやツイートの埋め込みなどの widgets を追加する方法 | mintsu's blog
https://blog.mintsu-dev.com/posts/2020-05-23-nuxt-spa-twitter-share/

vue-tweet-embed を使う

初めに使ったのは vue-tweet-embed です。screen_name が不要でツイートの ID だけで埋め込み表示までできるため結構重宝しました。

yarn add vue-tweet-embed

最初のうちはきちんとツイートが埋め込みで表示されてたのですが、README の方法で記述するとうまくいきません。

import Tweet from 'vue-tweet-embed/tweet'

現在の vue-tweet-embed だと yarn dev ができますが、コンパイルで次のエラーが出ます。

This dependency was not found:

  • vue-tweet-embed/tweet in ./node_modules/babel-loader/lib??ref--12-0!./node_modules/ts-loader??ref--12-1!./node_modules/@nuxt/components/dist/loader.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/index.vue?vue&type=script&lang=ts&

vue-tweet-embed が古いなどプロジェクトの構成によっては次のエラーが出て yarn dev すらできなくなります。

warning nuxt > @nuxt/webpack > @nuxt/babel-preset-app > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core
-js@3.
error [email protected]: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "11.4.0"
error Found incompatible module.

当時は解決できなくて 1-2 年ぐらい放置していたのですが、次の方法でうまくいきました。

import { Tweet } from 'vue-tweet-embed'

また、Tweet コンポーネントを読み込めても"Whoops! We couldn't access this Tweet. "が表示される場合は、ツイートの ID が JavaScript の仕様で丸められた可能性があります。
この場合は Twitter API でいう id_str を ID として使います。

このパッケージは 2020/12/16 現在で Last publish が a year ago になっているため、今後更新されない場合は先ほどの通常通りな方法を試すしかないようです。

TypeScript で使用する場合は自分で d.ts を作る必要がある

TypeScript を使ったコンポーネントで vue-tweet-embed 使うと型がないというエラーがでます。npm で型定義ファイルがないので自分で作る必要があります。

any 型とみなして良いのであれば次の内容で d.ts ファイルを作ります。そうでなければ vue-tweet-embed のパッケージからソースコードを自分で読んで自分で型を定義します。。。

types/vue-tweet-embed.d.ts
declare module "vue-tweet-embed";

作成した d.ts を使うように tsconfig.json の compilerOptionstypeRoots を追加します。

tsconfig.json
{
  "compilerOptions": {
    "typeRoots": ["types"],