以前の記事の今後やっていきたいことにもあげていた外部リンクの見た目を良くするためにRichLinkコンポーネントを作成しました。
使い方
<RichLink href="https://www.deg84.com/create-sitemap-with-gatsby/" />
解説
レンダリング時に取得しようとするとCORS(Cross-Origin Resource Sharing)の対策が必要なのでgatsby-node.jsでビルド時に情報を取得しておきます。
基本的にはOGPの内容を取得します。設定がない場合はmetaなどの情報から取得するようにしてみました。
取得するURLの一覧はYAMLで別途管理しておきます。
gatsby-node.js
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は現在非推奨になっているので要注意です。