prerender-spa-plugin
SPAをプリレンダリングして事前に各ページのhtmlを作って動的なOGPに対応する方法としてはrendertron、prerender.io、netlify などいろんな外部サービスがあるが、ページ数の少ないSPAの場合は、prerender-spa-plugin を使うのが一番お手軽だった。
使い方もwebpackに以下のような設定を入れておくだけ。
const PrerenderSPAPlugin = require("prerender-spa-plugin");
const path = require("path");
module.exports = (config, env) => {
if (env === "production") {
config.plugins = config.plugins.concat([
new PrerenderSPAPlugin({
routes: ["/", "/sign-in"], // 事前にレンダリングしておきたいページ
staticDir: path.join(__dirname, "build")
})
]);
}
return config;
};
このwebpackの設定をしている状態でビルドを行うと、以下のような感じで各ページごとにhtmlが吐き出される。
build
├── index.html
├── sign-in
│ └── index.html
あとはreact-helmetなどを使って各ページにmetaタグを入れておけば動的にogpが変わるようになる。
動作確認
動的にOGPが変わることをローカル環境で確認したい場合は、
- まずビルド行なう
- web-server-for-chromeや、serveなどを使ってビルド後のファイルが格納されているディレクトリを対象にサーバーを立てる。
- ngrokを使って 2 で立てたサーバーを外部公開する
- https://metatags.io/ などのogpが確認できるサイトに 3 で生成されたurlを貼り付ける。
をすれば確認できる。
ci
prerender-spa-plugin
は puppeteer
を使っているのでcircle ci上などでビルドしている場合は puppeteer
のインストールも必要。
https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-on-circleci
インストールしていない状態でビルドすると以下のようなエラーが出る。
Creating an optimized production build...
Error: Failed to launch chrome!
/home/circleci/repo/node_modules/puppeteer/.local-chromium/linux-686378/chrome-linux/chrome: error while loading shared libraries: libXtst.so.6: cannot open shared object file: No such file or directory
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
トラブルシューティングの説明にもあるように、以下のようなpuppeteerをインストールするコマンドを定義し、実行しておけば上記エラーは解消された。
commands:
puppeteer_install:
description: Install puppeteer and headless chrome
steps:
- run:
name: Install Headless Chrome dependencies
command: |
sudo apt-get install -yq \
gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates \
fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
- run:
name: Install puppeteer with chronium
command: |
yarn add puppeteer
prerender-spa-pluginはページが多いようなSPAだと不向きだが、個人で作ってるようなページ数が少ないSPAで使うなら必要十分なんじゃないかと感じた。