Notes

ウェブサイトをリニューアルした

6 min read

突然だが、ウェブサイトをリニューアルした。何を捨てて何を選んだか、その顛末のメモ。

4 年と 1 本

4 年前に「月に 1 本は書くぞ〜」と豪語したのに、結局書けたのは片手で数えるどころか 1 本である。約束は守れない方の人間だ。それでもこのドメインだけは更新料を払い続けてきたので、せめて器ぐらいは綺麗にしておきたい。

ウェブサイトの誕生 のときは、Notion をヘッドレス CMS にして OSS テンプレートに乗っかった。気軽に書ける反面、デザインは「OSS のまま」で、4 年経っても自分のものになっている感じがしなかった。AI に背中を押されたこともあって、今回は一から書き直すことにした。

Notion から、自前のスタックへ

2022 年のときは、Notion をヘッドレス CMS にして OSS テンプレ(nobelium)に乗っかっていた。記事は Notion 上のブロックで書き、フロントエンドは「OSS のまま」で動いている、という構成。

今回はそこを全部捨てた。テンプレートには乗らず、Next.js 16 (App Router) + React 19 + TypeScript でゼロから組み、Tailwind CSS v4 で見た目を当てた。

Notion から書き出していた頃は、フロント側のことを「いじれない箱」として扱っていた。その箱を全部開けて、自分の手で組み直した感がある。

記事の管理

記事は content/posts/*.mdx に MDX で置く。リニューアル直後は velite を使っていたが、2026 年 5 月に Next.js 純正の @next/mdx へ移行した。

コードハイライト

rehype-pretty-code + Shiki でビルド時にトークン化。ファイル名やフッターの挿入は自前の rehype プラグイン (lib/rehype-code-footer.mjs) で処理している。

埋め込み

  • ツイート: react-tweet
  • 外部 URL: OGP を node-html-parser で取得して自前のカードコンポーネントで描画

リアクション (Like)

ストレージは Vercel KV、レート制限は Upstash Ratelimit。

ホスティング / アナリティクス

Vercel + @vercel/analytics

CI / Lint / Format

GitHub Actions で biome checktsc --noEmitnext build の直列。Lint と format は Biome

フィード / サイトマップ / OG

app/feed.xml (Atom)、app/feed.json (JSON Feed)、app/sitemap.ts / app/robots.ts、OG 画像は app/api/og-lab/ で動的生成。

構造化データ

JSON-LD で Person / WebSite / Organization/aboutapp/layout.tsx から提供。

アイコン・アニメーション

  • アイコン: lucide-react + react-icons
  • アニメーション: motion (旧 framer-motion v12)

ヘッダーをやめた

リニューアルで一番悩んだのはヘッダーだ。サイトの一番上にナビがあるのは「礼儀」みたいなもので、無くすと不安になる。けれど、ロゴ+メニューが乗っていると、それだけで一気に「業務的」になってしまう。

割り切ってヘッダーを完全撤去し、Notes / About / RSS は全部フッターに移した。何もない上の余白の方が、自分にとっては大事だった。

葉影、シェーダーから動画へ

トップに置きたかったのは、白い壁の上で葉影がゆっくり揺れる背景だった。最初はかっこつけて WebGL から書こうとした。

ogl で fragment shader を書き、fbm ノイズで葉のシルエットを procedural に生成しようとした。出力は「煙」になり、パラメータをいじると今度は「顕微鏡で見た微生物」になった。手を動かすほど主張が強くなって、侘び寂びから遠ざかっていく。

途中で procedural に作るのは諦めた。実物の葉影が風で揺れている動画を、<video>mix-blend-mode: multiply で薄く重ねるだけ、に切り替えた。

// components/leaf-shadow-video.tsx (抜粋)
<video
  src="/video/leaf-shadow.mp4"
  autoPlay muted playsInline loop
  style={{
    objectFit: "cover",
    mixBlendMode: "multiply",
    opacity: 0.3,
  }}
/>

素材は Pexels で見つけた CC0 の葉影動画を、ffmpeg で 720p / グレースケール / シームレスループ加工した 400KB ほどの MP4。xfade で末尾と先頭を 1.5 秒重ねるとループの継ぎ目がほぼ見えなくなる。

ffmpeg -i leaf-cut.mp4 -filter_complex \
  "[0:v]split=2[a][b];[b]trim=start=0:end=1.5,setpts=PTS-STARTPTS[head];\
   [a][head]xfade=transition=fade:duration=1.5:offset=8.0[v]" \
  -map "[v]" -an -c:v libx264 -crf 28 -movflags +faststart \
  public/video/leaf-shadow.mp4

WebGL で書いていた数時間が無駄だったかというと、そうでもない。procedural では出せない領域を、自分の手で一度通ったからこそ、「実物の動画を薄く重ねるだけ」という地味な解に 納得して たどり着けた。最初から動画にしていたら、たぶん「もっとシェーダーで頑張れたんじゃないか」が頭の片隅に残り続けたと思う。

月に 1 本

「月に 1 本」は前回も果たせなかった。器がきれいになったところで、書く頻度が劇的に変わるかというと、たぶんそんなことはない。

正直なところ、Notion からローカル MDX に移したのは、書きやすさのためではない。Notion は今も日常で使っていて、書くこと自体の腰の重さは元々ない。むしろ git にコミットして push する MDX のほうが、操作としては面倒だ。書く/書かないをツールの摩擦のせいにするのは嘘で、自分の場合は メンタリティ の方が大きい。

承認欲求が先に立つと、書くためのインプットさえ「アウトプット起点」になりやすい。先に「出したい」「認められたい」があって、それを満たすための材料探しとして本を読み、コードを書き、世界を眺める。順序が逆になると、書けるものは増えても、書きたいものは増えない。

哲学者の韓炳哲(ハン・ビョンチョル)は 『疲労社会』 で、現代を 「自己搾取 (Selbstausbeutung)」 の時代と呼んだ。外から駆り立てられるのではなく、自由なはずの自己が、自分自身に「もっと出せ」と要求し続ける構造になっている、という診断だ。承認欲求は、内面化された監督官として勝手に鳴り続ける。

アラスデア・マッキンタイアの言い方を借りれば、書くという「実践 (practice)」には 内的善(書くこと自体に内在する価値)と 外的善(承認・名声)の二種類があり、後者を目的にした瞬間に前者が痩せる(『美徳なき時代』)。書きたいから書く、ではなく、認められたいから書く、に動機がすり替わった瞬間に、書くこと自体は空洞化する。

ともあれ、器はできた。次に問われるのは、ツールではなく自分のほうだ。