icon

Blog

本ブログをReact SPAからNext.jsにリプレイスした

2022/01/09

さすがにSPAだとSEO対策やOGP対応できないのでNext.jsに移行した。


やったこと

  • とりあえず作ったCreate React App製のこのブログをNext.jsに移行した
  • SSGとしてビルドしてVPS上にデプロイしnginx経由でアクセスできるようにした
  • このブログアプリはDBの読み込みのみで、ブログの編集に関してはこのアプリではやらず、別のエディターとAPIを用意する(後で書く)

Next.js

getStaticPropsはDBに直接アクセスすればいい

/pages/api にDBアクセスするAPIを書いて /pages のgesStaticPropsからAPIを呼び出すのかと思ってたが、getStaticProps内で直接DBアクセスすることでデータを取得できた。APIという依存が1つ減っただけでかなりすっきりした実感がある。

getStaticPathsで動的なルーティングを設定する

どうやって posts/[id].html のようなルーティングができるようになるのかと不思議に思ってたら export getStaticPaths することで対応できた。

export async function getStaticPaths() {
  const results = JSON.parse(JSON.stringify(await query('SELECT * FROM post WHERE published = true')))
  const paths = results.map((post: any) => `/posts/${post.id}`)
  return { paths, fallback: false }
}

Serverless MySQL

今回、データはfirestoreからMySQLを使うことにしたので、DBへのアクセスが必要になった。Next.jsからのMySQLクライアントラッパーで一番使われてそうだったので serverless-mysql を使った。

Next.jsのサンプルを参考に、薄いwrapperを作成して使いやすくした。 https://github.com/92thunder/blog/blob/main/blog/libs/db.ts

Material UI 5への対応

Material UIから4から5へ変わっていたがpackage名の変更くらいしか影響がなかった

SSGのビルド

buildしてからexportすることで静的なHTMLを生成することができる。2GBのVPSだとビルド失敗することあってわりと厳しめ。

  "scripts": {
    ...
      "build": "next build && next export",
    ...
  }

nginxの設定

SPA用の設定だとだめだったので、ここを参考にしてpathに応じてNext.jsのルーティングに対応したHTMLを返すように設定した

https://gist.github.com/zackad/7dd46be60df4fe7d1010a0fcf33d1afc

今後やりたいこと

  • ブログのエディターにPublishボタンを用意しておき、API経由でSSGを再ビルド
  • スタイルがうまくいってないところあるので改善する。。。