Reactで作ったページにTwitterCardsとOGPのメタデータを埋める
reactせっかくページを作ったので、SNSにシェアするときに見栄えをよくしたい。
Twitter CardsやOGPのmetaタグを埋めるとTwitterやFacebookにURLを貼ったときに上のように表示されるようになる(上はFacebookの例)。そこで、react-helmetでこんな感じで動的に埋め込んだんだが読んでくれない。
<Helmet title={'sambaiz.net'}
meta={[
{"name": "twitter:card", "content": "summary"},
{"name": "twitter:site", "content": "@sambaiz"},
{"name": "twitter:title", "content": "sambaiz.net"},
{"name": "twitter:description", "content": "僕のホームページ"},
{"property": "og:title", "content": "sambaiz.net"},
{"property": "og:type", "content": "blog"},
{"property": "og:image", "content": "http://d2wgaf7ubdj1mv.cloudfront.net/my.jpg"},
{"property": "og:url", "content": "https://www.sambaiz.net"}
]}
/>
GoogleのクローラーのようにJavascriptを解釈してくれる と思っていた。
しょうがないのでここだけサーバーサイドレンダリングすることにした。
'use strict'
import express from 'express'
import path from 'path'
import compression from 'compression'
require('isomorphic-fetch');
var app = express()
app.use(compression())
// serve our static stuff
app.use(express.static(path.join(__dirname, '..', '..', 'public')))
app.get('/', function (req, res) {
res.status(200).send(page('https://www.sambaiz.net', 'sambaiz.net', '僕のホームページ'));
})
app.get('/article/:articleId', function (req, res) {
fetch(`https://zx9h12n6jb.execute-api.ap-northeast-1.amazonaws.com/api/articles/${req.params.articleId}`).then(function(response){
if (response.status == 404) {
res.status(404).send('not found')
}else if(response.status != 200){
res.status(response.status).send(`API error ${response.status}`)
}else{
return response.json();
}
}).then(function(json) {
if(json){
res.status(200).send(page(`https://www.sambaiz.net${req.url}`, json.title, '書いた'));
}
})
})
function page(fullUrl, title, description) {
return `
<!doctype html>
<html>
<head>
<title>${title}</title>
<meta charset="utf-8">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@sambaiz">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
<meta property="og:title" content="${title}">
<meta property="og:type" content="blog">
<meta property="og:image" content="http://d2wgaf7ubdj1mv.cloudfront.net/my.jpg">
<meta property="og:url" content="${fullUrl}">
</head>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
</body>
</html>
`
}
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
console.log('Production Express server running at localhost:' + PORT)
})
ちゃんと読まれているかは以下のページで確認できる。