GatsbyJSの外部リンクをリッチにする
以前の記事の今後やっていきたいことにもあげていた外部リンクの見た目を良くするために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 })
}
}
出力結果
おわりに
はじめはogp-parserを使おうと思ったんですがインストール上手くいかなかったので、Axiosとcheerioでやってみることにしました。
ちなみにrequest npmは現在非推奨になっているので要注意です。