nuxt3 について
Nuxt 3 開発者向けのリファレンススキルです。ディレクトリ構成、データ取得、サーバールート、本番環境の設定を扱い、実装時の問題の確認にも役立ちます。
主な機能
- 01Nuxt 3 の構成とルーティングの解説
- 02SSR 対応のデータ取得
- 03サーバー API ルートの例
- 04ハイブリッドレンダリングと Nitro
- 05セキュリティ、性能、テストのチェックリスト
活用シーン
- 01Nuxt 3 プロジェクト構成の検討
- 02ページのデータ取得方法の選択
- 03サーバールートとレンダリングルールの設定
- 04自動インポートや SSR の問題の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill nuxt3インストール後、Claude Code で/nuxt3を入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
advanced.mdquick-ref/data-fetching.mddirectory-structure.md詳細
Nuxt 3 のコア知識
完全なリファレンス:WebSocket コンポーザブル、Nitro WebSocket ハンドラー、Socket.IO 統合、プラグインパターン、SSE、ルーム管理パターンについては、advanced.md を参照してください。
詳細な知識:包括的なドキュメントについては、テクノロジーに
nuxtを指定してmcp__documentation__fetch_docsを使用してください。
ディレクトリ構造
| ディレクトリ | 目的 |
|---|---|
pages/ | ファイルベースのルーティング |
components/ | 自動インポートされるコンポーネント |
composables/ | 自動インポートされるコンポーザブル |
server/ | サーバールートとミドルウェア |
layouts/ | ページレイアウト |
middleware/ | ルートミドルウェア |
ページコンポーネント
<script setup lang="ts">
// Auto-imports work: ref, computed, useFetch, etc.
const { data, pending } = await useFetch('/api/users')
definePageMeta({
layout: 'admin',
middleware: 'auth'
})
</script>
<template>
<div v-if="pending">Loading...</div>
<div v-else>{{ data }}</div>
</template>
データ取得
| コンポーザブル | 目的 |
|---|---|
useFetch | キャッシュ機能を備えた SSR 対応のフェッチ |
useAsyncData | カスタムの非同期処理 |
$fetch | 直接フェッチ(SSR 処理なし) |
useLazyFetch | 非ブロッキングフェッチ |
サーバールート
// server/api/users.get.ts
export default defineEventHandler(async (event) => {
const query = getQuery(event)
return await db.users.findMany()
})
// server/api/users.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return await db.users.create(body)
})
主な機能
- 自動インポート(コンポーネント、コンポーザブル、ユーティリティ)
- ハイブリッドレンダリング(SSR、SSG、ISR、SPA)
- Nitro サーバーエンジン
useStateによる組み込みの状態管理
このスキルを使用しない場合
このスキルは Nuxt 3(Vue メタフレームワーク)向けです。以下には使用しないでください。
- Nuxt を使わない Vue:代わりに
frontend-vueスキルを使用してください - Nuxt 2:Nuxt 3 への移行については KB を参照してください
- Next.js(React メタフレームワーク):代わりに
nextjs-app-routerスキルを使用してください - Remix(React メタフレームワーク):代わりに
remixスキルを使用してください - SvelteKit:代わりに
sveltekitスキルを使用してください - Astro:代わりに
astroスキルを使用してください - Vite のみのセットアップ:Vite の設定には
frontend-vueを使用してください
アンチパターン
| アンチパターン | 問題となる理由 | 正しいアプローチ |
|---|---|---|
| useFetch の代わりに $fetch を使用する | SSR 処理がなく、データもキャッシュされません | SSR 対応のフェッチには useFetch を使用します |
| onMounted でフェッチする | クライアント側のみで動作し、SSR が行われません | setup 内で useFetch/useAsyncData を使ってフェッチします |
| 自動インポートを使用しない | 不要なボイラープレートが増えます | コンポーネントやコンポーザブルには自動インポートを利用します |
| public runtimeConfig にシークレットを設定する | クライアントに公開され、セキュリティ上のリスクがあります | サーバー専用の runtimeConfig(public ではないもの)を使用します |
| ルートルールを無視する | パフォーマンス向上の機会を逃します | ルートごとに prerender、swr、または ssr のルールを設定します |
| error.vue がない | エラー時の UX が劣化します | グローバルなエラー処理用に error.vue を作成します |
よくある問題の簡単な解決方法
| 問題 | 考えられる原因 | 解決方法 |
|---|---|---|
| "useFetch is not defined" | 自動インポートが機能していない | .nuxt/tsconfig.json が生成されていることを確認し、開発サーバーを再起動します |
| SSR でデータを利用できない | useFetch ではなく $fetch を使用している | $fetch を useFetch に置き換えます |
| "useState is not defined" | 自動インポートの問題 | useState コンポーザブルを使用し(Nuxt 3)、.nuxt がビルドされていることを確認します |
| 本番環境で API ルートが 404 になる | ルートが生成されていない | server/api/ の構造を確認し、再ビルドします |
| ハイドレーションの不一致 | サーバーとクライアントでレンダリング結果が異なる | を使用し、一貫した状態を保ちます |
| コンポーネントが自動インポートされない | components/ ディレクトリにない | components/ に移動するか、nuxt.config で設定します |
本番環境への準備
セキュリティ設定
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Server-only (not exposed to client)
dbPassword: process.env.DB_PASSWORD,
// Exposed to client via useRuntimeConfig()
public: {
apiBase: process.env.API_BASE,
},
},
});
エラー処理
<script setup lang="ts">
import type { NuxtError } from '#app';
const props = defineProps<{ error: NuxtError }>();
const handleError = () => clearError({ redirect: '/' });
</script>
<template>
<div class="error-page">
<h1>{{ error.statusCode }}</h1>
<p>{{ error.message }}</p>
<button @click="handleError">Go Home</button>
</div>
</template>
パフォーマンス
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/blog/**': { swr: 3600 }, // Stale-while-revalidate
'/admin/**': { ssr: false }, // Client-only
},
});
API のセキュリティ
// server/api/users.post.ts
export default defineEventHandler(async (event) => {
// Validate input
const body = await readValidatedBody(event, (body) => {
return z.object({
email: z.string().email(),
name: z.string().min(2),
}).parse(body);
});
// Auth check
const session = await requireAuth(event);
return await createUser(body);
});
テスト
import { mountSuspended } from '@nuxt/test-utils/runtime';
import IndexPage from '~/pages/index.vue';
describe('Index Page', () => {
it('renders correctly', async () => {
const component = await mountSuspended(IndexPage);
expect(component.text()).toContain('Welcome');
});
});
監視メトリクス
| メトリクス | 目標 |
|---|---|
| Time to First Byte | < 200ms |
| First Contentful Paint | < 1.5s |
| ハイドレーション時間 | < 500ms |
| API 応答時間 | < 100ms |
チェックリスト
- セキュリティヘッダーの設定
- シークレット用のランタイム設定
- エラー処理(error.vue、プラグイン)
- ルートルール(prerender、swr、ssr)
- 画像の最適化
- コンポーネントの遅延読み込み
- API のバリデーション(Zod)
- API ルートのレート制限
- 保護されたルート用の認証ミドルウェア
- @nuxt/test-utils を使った E2E テスト
リファレンスドキュメント
コメント
Markdown 対応