GatsbyJSの外部リンクをリッチにする

GatsbyJSの外部リンクをリッチにする
Photo by Zetong Li / Unsplash

以前の記事の今後やっていきたいことにもあげていた外部リンクの見た目を良くするためにRichLinkコンポーネントを作成しました。

使い方

https://www.deg84.com/create-sitemap-with-gatsby/

解説

レンダリング時に取得しようとするとCORS(Cross-Origin Resource Sharing)の対策が必要なのでgatsby-node.jsでビルド時に情報を取得しておきます。

基本的にはOGPの内容を取得します。設定がない場合はmetaなどの情報から取得するようにしてみました。

取得するURLの一覧はYAMLで別途管理しておきます。

exports.onCreateNode = async ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  // 中略
  if (node.internal.type === 'LinksYaml') {
    const data = {
      url: node.url,
      domain: url.parse(node.url).hostname,
      title: '',
      description: '',
      image: '',
    }
    const res = await axios.get(node.url) // axiosを使ってリクエスト
    const $ = cheerio.load(res.data) // 結果をcheerioでパース

    // url
    if ($("meta[property='og:url']").attr('content'))
      data.url = $("meta[property='og:url']").attr('content')
    else if (res.request.res.responseUrl) {
      data.url = res.request.res.responseUrl
    }

    // domain
    data.domain = url.parse(data.url).hostname

    // title
    if ($("meta[property='og:title']").attr('content}'))
      data.title = $("meta[property='og:title']").attr('content}')
    else if ($('title').text()) {
      data.title = $('title').text()
    }

    // description
    if ($("meta[property='og:description']").attr('content'))
      data.description = $("meta[property='og:description']").attr('content')
    else if ($("meta[name='description']").attr('content')) {
      data.description = $("meta[name='description']").attr('content')
    }

    // image
    if ($("meta[property='og:image']").attr('content'))
      data.image = $("meta[property='og:image']").attr('content')
    else if ($("meta[name='image']").attr('content')) {
      data.image = $("meta[name='image']").attr('content')
    }

    // GraphQLで取得できるようにfieldsに入れる
    createNodeField({ name: 'url', node, value: data.url })
    createNodeField({ name: 'domain', node, value: data.domain })
    createNodeField({ name: 'title', node, value: data.title })
    createNodeField({ name: 'description', node, value: data.description })
    createNodeField({ name: 'image', node, value: data.image })
  }
}

出力結果

GatsbyJSでsitemap.xmlを出力する - deg84’s blog

おわりに

はじめはogp-parserを使おうと思ったんですがインストール上手くいかなかったので、Axiosとcheerioでやってみることにしました。

ちなみにrequest npmは現在非推奨になっているので要注意です。

参考サイト