Next.jsでブログをつくってみる
記念すべき一投目はこのブログを作るところから。
Next.jsで作ってみるか
最近はReactばかり触っているのであまり深く考えずにNext.jsを選定。
今回はじめて作るのでVercel公式のNext.js Blog Starter Kits & Templatesをボイラープレートにして作っていきます。
このサンプルに対応するGitHubリポジトリはnext.js/examples/blog-starterです。
コードをざっと確認したところReact 19ベースでApp Router使用, TypeScript。Tailwind v3で、コンポーネントのスタイル指定はCSS Modulesを併用しているっぽいです。
npx create-next-app --example blog-starter blog-starter-appPrettierとESLintを導入する
サンプルのファイルにはフォーマッタやLinterが設定されていないので、設定します。
ESLintの設定に関してはConfiguration: ESLint | Next.js参照。
npm i -D eslint eslint-config-next eslint-config-prettierPrettierとあわせてimport行を並べ替えるプラグインと、Tailwind公式のCSSクラスをいい感じにソートするプラグインを入れておきます。cf. Automatic Class Sorting with Prettier - Tailwind CSS
npm i -D prettier @trivago/prettier-plugin-sort-imports prettier-plugin-tailwindcssその他にやることとしては、Faviconの差し替えでしょうか。今回はfavicon.ioでまとめて生成しました。
Tailwindをv3 -> v4にアップグレード
ここでTailwindCSSをv4にアップグレードすることにします。Tailwind公式のUpgrade guideでマイグレーションツールが紹介されていたので、使います。
npx @tailwindcss/upgradeTailwindの設定ファイルの内容がグローバルCSSに移行されました。
さっそく開発サーバーがエラーを吐きました。
CssSyntaxError: tailwindcss: C:\path\to\src\app\_components\markdown-styles.module.css:1:1: Cannot apply unknown utility class `text-lg`. Are you using CSS modules or similar and missing `@reference`? https://tailwindcss.com/docs/functions-and-directives#reference-directive
@referenceをミッシングしているらしいのでCSS Modulesファイルの冒頭に参照をはります。
@reference "tailwindcss";
さらに、PrettierのTailwindプラグインが動作していないことにも気付きました。プラグインのREADMEを見たら、Tailwind v4の場合はtailwindStylesheetキーでCSSのエントリーポイントを特定しないといけないと書かれていました。
最終的に.prettierrcはこんな感じ。
{
"trailingComma": "es5",
"semi": true,
"singleQuote": false,
"plugins": [
"@trivago/prettier-plugin-sort-imports",
"prettier-plugin-tailwindcss"
],
"importOrder": [
"^react$",
"^next$",
"<BUILTIN_MODULES>",
"<THIRD_PARTY_MODULES>",
"^@/[^/]+/(.*)$",
"^[./]"
],
"tailwindStylesheet": "./src/app/globals.css"
}SSGでビルドしてGitHub Pagesにデプロイする
結局サンプルをいったん更地にしてコンポーネントを作り直し、ダークモードも自分で実装してみたのですが、通常のReactアプリとは異なりUIがフリッカ―する問題があるので、少し手こずりましたね。その話は別記事にします。
SSGでビルドするにはnext.config.jsを以下のように設定しておきます。
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
output: "export",
trailingSlash: true,
distDir: "dist",
};
module.exports = nextConfig;next buildコマンドでビルドすると静的HTMLが生成されます。次にnext startを使うとSSRになってしまうので、ローカルでの動作確認はnpx serve distコマンドを使います。
デプロイ先はお手軽さ優先でGitHub Pagesに。GitHub Actionsのワークフローで自動的にビルドとデプロイを実行します。
ワークフローを記述するYAMLファイルは、あらかじめNext.js用のテンプレートが用意されているので、ほぼデフォルトのまま使うことができます。変更の監視範囲(_postsとapp)と出力フォルダ(outからdistに変更)の設定だけ変更しました。
ここまで作ったあとで気づいたのですが、Blog StarterよりもNext.js Portfolio StarterのほうがダイナミックOG画像生成やシンタックスハイライトがあらかじめ設定されており、使いやすいかもしれません。
現時点では、とりあえずページを表示できるだけの状態なので、改善を重ねて使いやすいものにしていきたいと思います。