Nuxt 4 におけるアーキテクチャの引き算
コンテンツ中心のサイトに複雑なフロントエンド状態は不要です。ルーティング、SSR、コンテンツクエリを、それぞれ得意な場所へ戻します。

Nuxt プロジェクトが複雑になる理由は、ビジネスが本当に複雑だからとは限りません。あらゆる将来の可能性を、あまりに早くアーキテクチャへ入れてしまうことがよくあります。
個人ブログは良い調整基準になります。ページ数は限られ、コンテンツ構造は安定し、インタラクションは少数の領域に集中しています。フレームワークの最も価値ある役割は、機能を増やすことではなく、不要な選択肢を削除することだと気づかせてくれます。
デフォルトの SSR から始める
技術記事は検索エンジンに理解される必要があり、低速な回線でも本文をできるだけ早く表示したいものです。Nuxt のデフォルトであるサーバーサイドレンダリングは、その目的に合っています。
export default defineNuxtConfig({
modules: ['@nuxt/content'],
nitro: {
preset: 'cloudflare',
},
})
サイト全体を SPA に変える必要も、ページごとに別のデータ取得方法を発明する必要もありません。最初のクエリとレンダリングはサーバーで完了し、クライアントが引き継いだ後も同じルーターを使います。
ブラウザ API に依存する小さな領域だけ、局所的に ClientOnly を使えば十分です。一つのクライアントコンポーネントのために、ページ全体のセマンティクスとファーストビューを犠牲にしてはいけません。
コンテンツクエリをページ境界に置く
ホーム、記事一覧、記事詳細では必要なデータ粒度が異なります。クエリは利用するページの近くに置きます。
const { data: posts } = await useAsyncData('latest-posts', () => {
return queryCollection('posts')
.where('draft', '=', false)
.order('publishedAt', 'DESC')
.limit(6)
.all()
})
この方法には直接的な利点があります。
- データが SSR に参加し、
onMounted後に点滅しながら表示されません。 - クエリキーが明確なので、Nuxt は hydration 時に payload を再利用できます。
- ページ自身が必要なものを理解し、汎用 store を経由する必要がありません。
- 下書きの除外と並び順が、本当に関係する場所に現れます。
複数のページが同じ複雑な業務状態を共有するようになったときにだけ、composable や store へ抽出する価値があります。
安定して繰り返すものだけをコンポーネント化する
「再利用できそう」はコンポーネント境界ではありません。本当に安定した繰り返しには、通常、構造、意味、動作が同時に含まれます。
このブログでは記事カードが適切なコンポーネントです。ホームと一覧ページの両方に現れ、メタデータ、タイトル、概要、タグ、遷移動作が固定されています。
一方、ホームの Hero は大きくても、必ずしも五つの小さなコンポーネントへ分割する必要はありません。一つのページにしか現れず、内部要素がまとまって一つの視覚的な物語を作ります。早すぎる分割は、スタイルの関係を複数ファイルへ散らすだけです。
コンポーネントはファイル整理の道具ではなく、独立して理解し再利用できる UI 契約です。
サーバー API のインターフェースを狭く保つ
ログインとコメントは実行時データなので server/api に置きます。各 endpoint は一つの仕事だけを行います。
POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
GET /api/auth/session
GET /api/comments/:post
POST /api/comments/:post
狭いインターフェースは認可規則を確認しやすくします。コメントの読み取りは公開、作成にはセッションが必要、ログアウトはユーザープロフィールに触れず現在のトークンだけを破棄します。
一つの endpoint が読み取り、書き込み、ログイン、形式変換を同時に扱うなら、すでに明確な境界を失っています。
状態を正しい場所へ戻す
Vue のリアクティブな状態は便利ですが、すべての状態を JavaScript に置くべきではありません。
| 状態 | 最適な場所 |
|---|---|
| 現在の記事 | ルート |
| 検索語 | ページの ref |
| タグ絞り込み | URL query + ページ状態 |
| ログインユーザー | SSR 安全な useState |
| 記事本文 | Nuxt Content |
| セッションの真正性 | サーバー側の D1 |
状態を正しい場所へ置けば、大量の「同期ロジック」が自然に消えます。ルートを監視して store を修復する必要も、localStorage でログイン状態が信頼できるふりをする必要もなくなります。
引き算は機能を減らすことではない
良いアーキテクチャの引き算は、ユーザーから何も奪いません。むしろ、ユーザーが実際に感じる部分へ複雑さの予算を残します。
- より明確なタイポグラフィ。
- より速いファーストビュー。
- より信頼できるログイン。
- より快適なモバイル読書。
- 続けやすい Markdown 執筆フロー。
Nuxt 4 には十分な機能があります。成熟したプロジェクトとは、それらをすべて使うものではなく、今は使わなくてよい機能を知っているものです。
コメント
ログインして議論に参加
メールアドレスは公開されず、表示名だけが表示されます。