Vue 3のSSR/SSGとNuxt 3入門:サーバーサイドレンダリング、静的生成、およびNuxtフルスタック
SSR(サーバーサイドレンダリング)とSSG(静的サイト生成)は、Vueアプリケーション向けの高度なデプロイ手法であり、CSR(クライアントサイドレンダリング)に比べて、最初のページの読み込み時間が短縮され、SEO効果も向上します。Nuxt 3は、Vue 3向けのSSRフレームワークであり、ルーティング、状態管理、SEO最適化の機能を標準で備えています。
CSR、SSR、SSGという3つのレンダリングモードを理解することで、それぞれのシナリオに適した適切なデプロイ方法を選択できるようになります。このレッスンでは、SSRとSSGに関する確かな基礎知識を身につけることができます。
1. 学習内容
- 3つの主要なレンダリングモード(CSR、SSR、SSG)の比較
- SSRの5つの主なユースケース
- Nuxt 3 の完全なディレクトリ構造
- Nuxt 3 の Composable API(useState / useFetch / useAsyncData)
- Nuxtの自動インポートとファイルルーティング
- Nuxtモジュールのエコシステム(@nuxtjs/tailwindcss など)
- よくある5つの間違い
2. Vue SPAにおける「最初の画面の5秒読み込み」というジレンマ
(1) 課題:CSRの最初の画面の読み込みが遅い + SEOがコンテンツをクロールできない
AliceのVue SPAには問題がありました:
TEXT
Traditional Vue SPA(CSR):
1. Browser Request → Returns null HTML(<div id="app"></div>)
2. Download JS(500KB)
3. Execute JS(Vue Start)
4. Rendered Content
5. Users view the content
Time to First View: 3-5s
SEO:Google Can't find the content(spa The content is JS Rendered)
プロダクトマネージャーのチャーリー:
「アリス、Googleでの順位が低いんだ。検索エンジンがコンテンツをインデックスできるように、サーバーサイドレンダリングされたHTMLが必要なんだ。それに、ファーストペイントの速度も向上させる必要がある。」
(2) Nuxt 3 の SSR ソリューション
TEXT
Nuxt 3 SSR:
1. Browser Request → Server-Side Rendering Complete HTML
2. Return with content HTML (Home Page 0.5s)
3. Download JS(hydration Required)
4. Client"Activate"(Take Over Interaction)
Time to First View: 0.5s
SEO:✅ Perfect(HTML Contents)
JS
// server/api/products.js(Nuxt 3 Automatic Routing)
export default defineEventHandler(async (event) => {
return await $fetch('https://api.example.com/products')
})
VUE
<!-- pages/products.vue(Automatic Routing) -->
<template>
<div>
<ProductCard v-for="product in products" :key="product.id" :product="product" />
</div>
</template>
<script setup lang="ts">
// useFetch Prefetching Data on the Server Side
const { data: products } = await useFetch('/api/products')
</script>
(3) 収益
Nuxt 3 SSR への移行後:
- 最初の表示可能なコンテンツまでの時間:3~5秒 → 0.5秒(-90%)
- SEOスコア:60 → 95(+35)
- Googleにインデックス登録済み:0ページ → 5,000件のSKUページすべて(+∞)
- ソーシャルシェア:カード 0 枚 → 完全プレビュー(Open Graph)
3. CSR 対 SSR 対 SSG
(1) 3つの主要なレンダリングモード
| モード | レンダリング時間 | スクロールせずに見える範囲 | SEO | サーバー負荷 |
|---|---|---|---|---|
| CSR(クライアントサイドレンダリング) | ブラウザ | 遅い(3~5秒) | ❌ 低 | 低 |
| SSR (サーバーサイドレンダリング) | リクエストごと | 中程度 (0.5~1秒) | ✅ 良好 | 高 |
| SSG (静的サイト生成) | ビルド時間 | **高速 (0.1~0.5 秒) | ✅ 完璧 | 最短 |
(2) SSRの5つの主なユースケース
| シナリオ | 推奨モード |
|---|---|
| コンテンツサイト(ブログ/ドキュメント/マーケティングページ) | SSG(最速+SEOに最適) |
| Eコマースの商品詳細(5,000 SKU) | SSR(リアルタイムデータ + SEO) |
| SaaS バックエンド(ログイン後) | CSR(SEO不要) |
| ソーシャルメディアプラットフォーム(動的コンテンツ) | SSR(リアルタイム + SEO) |
| 個人ブログ(限定コンテンツ) | SSG(最もシンプル) |
(3) SSRに比べてSSGが持つ5つの主な利点
| SSGのメリット | SSRのメリット |
|---|---|
| 最高速度(CDNからの直接配信) | リアルタイムデータ(リクエストごと) |
| サーバー負荷の最小化 | パーソナライズされたログイン体験 |
| 無制限のスケーラビリティ(CDN) | 動的コンテンツに最適 |
| ビルド後はサーバーが不要 | 対話型アプリケーションに最適 |
| Netlify / Vercel の無料ホスティング | Node.js サーバー |
4. Nuxt 3 の基礎
(1) プロジェクトを作成する
BASH
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev # Default http://localhost:3000
(2) ディレクトリ構造の全体像
TEXT
my-nuxt-app/
├── assets/ # Resources(Image、Font)
│ └── css/
│ └── main.css
├── components/ # Public Components
│ ├── AppHeader.vue
│ └── AppFooter.vue
│ └── product/
│ └── ProductCard.vue # Automatic Registration of Nested Directories
├── composables/ # Composite Functions
│ └── useAuth.ts
├── layouts/ # Layout
│ ├── default.vue # Default Layout
│ └── admin.vue # Backend Layout
├── middleware/ # Routing Middleware
│ └── auth.ts
├── pages/ # File Routing(Automatically Generated)
│ ├── index.vue # /
│ ├── about.vue # /about
│ ├── products/
│ │ ├── index.vue # /products
│ │ └── [id].vue # /products/:id
│ └── admin/
│ └── index.vue # /admin
├── plugins/ # Nuxt Plugins
│ └── pinia.ts
├── public/ # Static Resources
├── server/ # Server-side code
│ ├── api/ # API Routing(Automatic Registration)
│ │ └── products.ts # /api/products
│ └── middleware/ # Server-Side Middleware
├── stores/ # Pinia stores
├── app.vue # Root Component
├── nuxt.config.ts # Nuxt Layout
└── package.json
(3) ファイルのルーティング(自動)
TEXT
pages/index.vue → /
pages/about.vue → /about
pages/products/index.vue → /products
pages/products/[id].vue → /products/:id
pages/admin/index.vue → /admin
ルーティングテーブルを設定する必要はありません。そのファイル自体がルートだからです。
- Nuxt 3 コア API
(1) useFetch:サーバーサイドでのデータのプリフェッチ
VUE
<script setup lang="ts">
// useFetch: SSR when server executes, CSR when client runs
const { data, pending, error, refresh } = await useFetch('/api/products')
// 5 Large Return Values
// data: Response Data
// pending: Loading...
// error: Error Message
// refresh: How to Retrieve It Again
// status: Status Code
</script>
(2) useAsyncData:汎用的な非同期データ
VUE
<script setup lang="ts">
const { data } = await useAsyncData('products', () =>
$fetch('/api/products')
)
// Options: Cache, Dependency, Convert
const { data: users } = await useAsyncData(
'users',
() => $fetch('/api/users'),
{
cache: 'force-cache', // Force Caching
default: () => [] // Default value
}
)
</script>
(3) useState:コンポーネント間で共有され、SSRに対応したステート
VUE
<script setup lang="ts">
// useState Replace ref(SSR Friendly)
const cart = useState('cart', () => ({ items: [], total: 0 }))
// Edit
cart.value.items.push(product)
</script>
(4) 5 その他のコンポーザブル
TS
// 1. useFetch:Server-Side Data Prefetching
const { data } = await useFetch('/api/products')
// 2. useAsyncData:Generic Asynchronous
const { data } = await useAsyncData('key', fetcher)
// 3. useState:Global State(SSR Friendly)
const user = useState('user', () => null)
// 4. useRoute:Current Route
const route = useRoute()
// 5. useRuntimeConfig:Runtime Configuration
const config = useRuntimeConfig()
6. Nuxt 3 のコア設定
(1) nuxt.config.ts
TS
export default defineNuxtConfig({
// 1. Module
modules: [
'@nuxtjs/tailwindcss',
'@pinia/nuxt',
'@vueuse/nuxt'
],
// 2. CSS
css: ['~/assets/css/main.css'],
// 3. Runtime Configuration
runtimeConfig: {
apiSecret: 'xxx', // Server-side
public: {
apiBase: 'https://api.example.com' // Client
}
},
// 4. Rendering Mode
ssr: true, // Enable SSR
// 5. Application Configuration
app: {
head: {
title: 'My App',
meta: [
{ name: 'description', content: 'My app description' }
]
}
}
})
(2) 自動インポート(import は不要)
VUE
<script setup lang="ts">
// ✅ Nuxt Automatic Import:
// - Vue 3 API(ref, computed, watch)
// - Nuxt 3 composables(useFetch, useState)
// - Components(components/ Table of Contents)
// - utils/ Table of Contents
const count = ref(0)
const { data } = await useFetch('/api/products')
</script>
(3) 自動SEO最適化
VUE
<script setup lang="ts">
useHead({
title: 'iPhone 15 Pro - My Shop',
meta: [
{ name: 'description', content: 'Buy iPhone 15 Pro at best price' },
{ property: 'og:title', content: 'iPhone 15 Pro' },
{ property: 'og:image', content: '/iphone.jpg' }
]
})
</script>
7. 完全な例:Nuxtの5つの主要なシナリオ
(1) ▶ サンプル:. Nuxtの完全なディレクトリ構造
TEXT
my-nuxt-app/
├── pages/ # File Routing
├── components/ # Automatic Registration
├── composables/ # Automatic Import
├── server/api/ # API Routing
├── server/middleware/
├── middleware/ # Client-side middleware
├── plugins/ # Nuxt Plugins
├── layouts/ # Layout
└── nuxt.config.ts
(2) ▶ サンプル:. 5つの主要API
| API | 目的 |
|---|---|
useFetch |
サーバーサイドでのデータ取得 |
useAsyncData |
汎用非同期データ |
useState |
グローバル状態(SSR対応) |
useRoute |
現在のルート |
useRuntimeConfig |
実行時設定 |
(3) ▶ サンプル:. 5つの主要なNuxtモジュール
TS
modules: [
'@nuxtjs/tailwindcss', // Tailwind Integration
'@pinia/nuxt', // Pinia Status
'@vueuse/nuxt', // VueUse
'@nuxt/image', // Image Optimization
'nuxt-icon' // Icon
]
(4) ▶ サンプル:. 5つの主なユースケース
| シナリオ | Nuxtによる解決策 |
|---|---|
| コンテンツサイト | SSG (nuxi generate) |
| Eコマース | SSR (デフォルト) |
| バックエンド | CSR (ssr: false) |
| フルスタック | Nuxt + サーバー/API |
| 静的ブログ | SSG + Markdown |
(5) ▶ サンプル:. よくある5つの間違いに関するクイックリファレンス
| エラー | 症状 | 解決策 |
|---|---|---|
| useFetch のデータが表示されない | await がない | const { data } = await ... に変更 |
| SSRのハイドレーションエラー | データの不整合 | ref の代わりに useState を使用 |
| ルーティングが機能しない | ファイルパスが間違っている | pages/ ディレクトリに配置してください |
| モジュールのインストールに失敗しました | 名前が正しくありません | 「modules」のスペルを確認してください |
| SEO対象外 | ssr: false | SSRを有効にする |
❓ よくある質問
Q CSR、SSR、SSGのどれを選べばいいですか?
A コンテンツサイト(ブログ・ドキュメント)→ SSG。ECサイト・ソーシャルメディア → SSR。バックエンド・SaaS → CSR。Nuxt 3はこれら3つすべてに対応しています。
Q Nuxt 3 にはどのバージョンの Node.js が必要ですか?
A Node.js 18 以降(2023年10月現在)。Nuxt 2 では引き続き Node.js 16 がサポートされています。
Q useFetch と useAsyncData の違いは?
A useFetch は useAsyncData のシンタックスシュガー(特にフェッチ操作を扱うためのもの)です。ほとんどの場合、useFetch だけで十分です。
Q Nuxt 3 と Nuxt 2 の違いは?
A Nuxt 3(2022年11月)は、Vue 3、Vite、TypeScriptを標準機能としてサポートしています。Nuxt 2はメンテナンスモードに入っています。
Q SSG を作成するにはどうすればよいですか?
A
npx nuxi generate .output/public/ ディレクトリを生成し、Netlify、Vercel、または Cloudflare Pages にデプロイします。Q SSRサーバーに高負荷がかかっている場合はどうすればよいですか?
A (Nuxtに組み込まれている) Nitroサーバーを使用して、Vercel Edge、Cloudflare Workers、またはNodeクラスターにデプロイしてください。あるいは、SSGに切り替えてください。
📖 まとめ
- CSR / SSR / SSG:3つの主要なレンダリングモード:CSR(最初の画面の読み込みに3~5秒) / SSR(0.5~1秒) / SSG(0.1~0.5秒)
- SSRの5つの主な活用事例:Eコマース/ソーシャルメディア/リアルタイムデータ/ログイン状態/動的コンテンツ
- Nuxt 3 は、Vue 3 の公式 SSR フレームワークです
- ファイルのルーティング:「pages/」ディレクトリがルートとなります
- 5つの主要なAPI:useFetch / useAsyncData / useState / useRoute / useRuntimeConfig
- 自動インポート:Vue API + Nuxt コンポーザブル + コンポーネント + ユーティリティ
- Nuxt モジュールエコシステム:200 以上の公式およびコミュニティ提供のモジュール
- 自動SEO最適化:useHeadの動的設定
📝 練習問題
(1) 基礎問題(難易度:⭐)
Nuxt 3 プロジェクトを作成する:
- 3ページ(ホーム/会社概要/お問い合わせ)
- 1つのAPI(/api/hello)
- 上部ナビゲーション + 下部レイアウト
(2) 上級問題(難易度:⭐⭐)
Nuxt 3 での完全な SSR 機能の実装:
- 5ページ(ホーム/商品一覧/商品詳細/カート/ログイン)
- サーバー/API ルート (/api/products)
- useFetch: サーバーサイドのプリフェッチ
- useHead ダイナミックSEO
- ピニア州の管理
(3) チャレンジ問題(難易度:⭐⭐⭐)
完全な「エンタープライズグレードの Nuxt 3」プロジェクトの実装:
- 10ページ以上(ECサイト+管理画面+認証機能)
- 5つの主要なAPIルート
- 3つのレンダリングモード(SSR/SSG/CSRハイブリッド)
- SEO対策(構造化データ+オープングラフ+サイトマップ)
- パフォーマンスの最適化(画像の遅延読み込み/コード分割/CDN)
- Vercel Edge へのデプロイ
- TypeScriptの型を完全にする



