Top

Next.js ベースのブログに移行した話

この posts は?

blog を nextjs ベースに移行した理由や経緯と、環境構築の方法を備忘録として残すものです

なぜ Blog を移行したか

今までははてなブログや Qiita に投稿したり、会社のテックブログに投稿することが多かったのですが、いくつかの制約があって個人で管理できるものに移行しようと考えていました

  • はてなブログの ID を変更して継続したかったが ID 変更できなかった
  • Qiita には技術系の内容しかかけない
  • 会社のテックブログはもちろん会社の一員として執筆するので人格が違う

いっときは notion-blog (Notion を CMS として Blog 構築 できる OSS) を利用していた時期もあるのですが、しばらく放置していると API Token の期限が切れていたり、Notion の仕様に振り回されるので Blog は Blog として管理できるようにしようと思いたちました (将来的には Notion API が Private beta なのでこれに期待していたりします)

はてなブログ等のマネージドなブログサービスを使わなかった理由ですが、業務では go/kubernetes を触ることが多くフロントエンドを触る機会がほとんどないです。 そのため、個人ブログぐらい最低限継続的に触っておくことで Mock Application くらいは業務でさくっと作れるようになっておきたいなと思ったのが始まりです

年末年始の休みを利用して、簡易的なブログの雛形ができたので流れをかんたんに残しておきます

要件

以下の条件を達成できることです

  • markdown による記事管理
  • 箇条書き、リンク、コードブロックなど markdown で扱う基本的なレイアウトが表示可能
  • Embed Link、画像を扱える

要件チェック

- hoge
  - fuga
    - piyo

[ko-da-k's blog](https://blog.ko-da-k.dev/)

\`\`\`go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
}
\`\`\`

> これは引用文です

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Sunsets don&#39;t get much better than this one over <a href="https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw">@GrandTetonNPS</a>. <a href="https://twitter.com/hashtag/nature?src=hash&amp;ref_src=twsrc%5Etfw">#nature</a> <a href="https://twitter.com/hashtag/sunset?src=hash&amp;ref_src=twsrc%5Etfw">#sunset</a> <a href="http://t.co/YuKy2rcjyU">pic.twitter.com/YuKy2rcjyU</a></p>&mdash; US Department of the Interior (@Interior) <a href="https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw">May 5, 2014</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

結果

  • hoge
    • fuga
      • piyo

ko-da-k's blog

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
} 

これは引用文です

環境構築

環境

node: v14.15.3
npm: v6.14.10
next: v10.0.4

1. npx コマンドで雛形を立ち上げ

$ npx create-next-app --example blog-starter-typescript-app blog-starter-typescript-app` コマンドを利用してベース環境立ち上げ

これだけでブログの8割はできたと言っても過言ではないと思います (template が充実しているのは嬉しかったです)。 このコードは vercel/next.js/examples/blog-starter-typescript を参照しており、プロジェクトにそのまま展開されます。 これをベースに、他にほしい機能を整えていったり、細かいページレイアウトを調整していく感じになります。

2. prismjs の導入

prismjs: https://prismjs.com/

Installation

$ npm i prismjs
$ npm i --save-dev @types/prismjs

pages/_app.tsxcomponents/layout.tsx の 2 つのファイルを編集します

pages/_app.tsx

import React from "react";
import {AppProps} from 'next/app'
import '../styles/index.css'
import 'prismjs/themes/prism-tomorrow.css'  // これが追加

export default function MyApp({Component, pageProps}: AppProps) {
  return <Component {...pageProps} />
}

components/layout.tsx

import React, {useEffect} from "react";
import Prism from 'prismjs'
import 'prismjs/components/prism-jsx.min'
import 'prismjs/components/prism-go'
import 'prismjs/components/prism-css'
import 'prismjs/components/prism-tsx'
// (omitted)...

const Layout = ({preview, children}: Props) => {
  useEffect(() => {
    Prism.highlightAll();
  }, []);
  // (omitted)...
}

必要な syntax highlight の css import 及び、useEffect による highlight 有効化をします

3. markdown-styles.module.css で見た目を微調整

以下のような css を追加しました

/* テンプレそのままだと a tag に色がつかない */
.markdown a {
  @apply text-blue-600;
}

/* 箇条書きの位置がおかしいので、tailwindcss の `list-inside を適用する */
.markdown ul {
  @apply list-disc list-inside;
}

/* nest した箇条書きを認識しないので見た目を整える */
.markdown ul ul {
  @apply list-disc list-inside m-0 pl-4;
}

/* 数字付き箇条書きが整わないので、list-decimal にする */
.markdown ol {
  @apply list-decimal list-inside;
}

/* inline code で色が何も変わらないので見た目を変える */
.markdown code:not([class]) {
  @apply bg-gray-800 text-gray-200;
}


/* 引用が機能しないので CSS で整える */
.markdown blockquote:not([class]) {
  @apply bg-gray-100 text-gray-600;
}

4. vercel へのデプロイ設定

vercel: https://vercel.com

https://vercel.com/new に従ってデプロイ作業を進めれば大きな問題なく完了しました。

GitHub Integration を設定することで、main branch への push で production 反映されるようになっています

これから

ブログの細かい修正は空いている時間にやっていこうと思います。

去年の 2 月頃からフルリモートになり環境整えていたり、プライベートで色々あったのが一段落した感じがあります。 2021 年は生活にメリハリつけつつ、引き続き継続的な学習ができればいいなと思います。