ライフサイクルフック
Nuxtは、フックを使用してほぼすべての側面を拡張するための強力なフックシステムを提供します。
アプリフック(ランタイム)
利用可能なすべてのフックについては、アプリのソースコードを確認してください。
| フック | 引数 | 環境 | 説明 |
|---|---|---|---|
app:created | vueApp | サーバー & クライアント | 初期の vueApp インスタンスが作成されたときに呼び出されます。 |
app:error | err | サーバー & クライアント | 致命的なエラーが発生したときに呼び出されます。 |
app:error:cleared | { redirect? } | サーバー & クライアント | 致命的なエラーが発生したときに呼び出されます。 |
vue:setup | - | サーバー & クライアント | Nuxtルートのセットアップが初期化されたときに呼び出されます。このコールバックは同期的でなければなりません。 |
vue:error | err, target, info | サーバー & クライアント | Vueエラーがルートコンポーネントに伝播したときに呼び出されます。詳細はこちら。 |
app:rendered | renderContext | サーバー | SSRレンダリングが完了したときに呼び出されます。 |
app:redirected | - | サーバー | SSRリダイレクトの前に呼び出されます。 |
app:beforeMount | vueApp | クライアント | アプリのマウント前に呼び出され、クライアント側でのみ呼び出されます。 |
app:mounted | vueApp | クライアント | Vueアプリが初期化され、ブラウザにマウントされたときに呼び出されます。 |
app:suspense:resolve | appComponent | クライアント | Suspense 解決イベント時に呼び出されます。 |
app:manifest:update | { id, timestamp } | クライアント | アプリの新しいバージョンが検出されたときに呼び出されます。 |
app:data:refresh | keys? | クライアント | refreshNuxtData が呼び出されたときに呼び出されます。 |
link:prefetch | to | クライアント | <NuxtLink> がプリフェッチされるときに呼び出されます。 |
page:start | pageComponent? | クライアント | NuxtPage の保留イベント内で Suspense が呼び出されます。 |
page:finish | pageComponent? | クライアント | NuxtPage の解決イベント内で Suspense が呼び出されます。 |
page:loading:start | - | クライアント | 新しいページの setup() が実行されるときに呼び出されます。 |
page:loading:end | - | クライアント | page:finish の後に呼び出されます。 |
page:transition:finish | pageComponent? | クライアント | ページ遷移後の onAfterLeave イベント。 |
dev:ssr-logs | logs | クライアント | クライアントに渡されたサーバーサイドのログの配列と共に呼び出されます(features.devLogs が有効な場合)。 |
page:view-transition:start | transition | クライアント | 実験的なviewTransitionサポートが有効な場合 に document.startViewTransition が呼び出された後に呼び出されます。 |
Nuxtフック(ビルド時)
利用可能なすべてのフックについては、スキーマのソースコードを確認してください。
| フック | 引数 | 説明 |
|---|---|---|
kit:compatibility | compatibility, issues | 互換性チェックを拡張することができます。 |
ready | nuxt | Nuxtの初期化後、Nuxtインスタンスが作業可能になったときに呼び出されます。 |
close | nuxt | Nuxtインスタンスが正常に閉じるときに呼び出されます。 |
restart | { hard?: boolean } | 現在のNuxtインスタンスを再起動するために呼び出されます。 |
modules:before | - | Nuxtの初期化中、ユーザーモジュールのインストール前に呼び出されます。 |
modules:done | - | Nuxtの初期化中、ユーザーモジュールのインストール後に呼び出されます。 |
app:resolve | app | app インスタンスの解決後に呼び出されます。 |
app:templates | app | NuxtApp の生成中に呼び出され、ビルドディレクトリに新しいファイルをカスタマイズ、変更、または追加することができます(仮想的にまたは .nuxt に書き込むために)。 |
app:templatesGenerated | app | テンプレートが仮想ファイルシステム (vfs) にコンパイルされた後に呼び出されます。 |
build:before | - | Nuxtバンドルビルダーの前に呼び出されます。 |
build:done | - | Nuxtバンドルビルダーが完了した後に呼び出されます。 |
build:manifest | manifest | Viteとwebpackによるマニフェストビルド中に呼び出されます。Nitroが最終HTMLで <script> と <link> タグをレンダリングするために使用するマニフェストをカスタマイズすることができます。 |
builder:generateApp | options | アプリの生成前に呼び出されます。 |
builder:watch | event, path | 開発中にビルド時にウォッチャーがプロジェクト内のファイルまたはディレクトリの変更を検出したときに呼び出されます。 |
pages:extend | pages | ファイルシステムからページルートがスキャンされた後に呼び出されます。 |
pages:resolved | pages | ページルートがスキャンされたメタデータで拡張された後に呼び出されます。 |
pages:routerOptions | { files: Array<{> } | router.options ファイルを解決するときに呼び出されます。配列内の後の項目は前の項目を上書きします。 |
server:devHandler | handler | Nitro開発サーバーで開発ミドルウェアが登録されるときに呼び出されます。 |
imports:sources | presets | セットアップ時にモジュールがソースを拡張できるようにします。 |
imports:extend | imports | セットアップ時にモジュールがインポートを拡張できるようにします。 |
imports:context | context | unimport コンテキストが作成されるときに呼び出されます。 |
imports:dirs | dirs | インポートディレクトリを拡張することができます。 |
components:dirs | dirs | app:resolve 内で呼び出され、自動インポート可能なコンポーネントをスキャンするディレクトリを拡張することができます。 |
components:extend | components | 新しいコンポーネントを拡張することができます。 |
nitro:config | nitroConfig | Nitroの初期化前に呼び出され、Nitroの設定をカスタマイズすることができます。 |
nitro:init | nitro | Nitroが初期化された後に呼び出され、Nitroフックの登録やNitroとの直接のやり取りが可能です。 |
nitro:build:before | nitro | Nitroインスタンスのビルド前に呼び出されます。 |
nitro:build:public-assets | nitro | 公開アセットのコピー後に呼び出されます。Nitroサーバーがビルドされる前に公開アセットを変更することができます。 |
prerender:routes | ctx | プリレンダリングされるルートを拡張することができます。 |
build:error | error | ビルド時にエラーが発生したときに呼び出されます。 |
prepare:types | options | @nuxt/cli が .nuxt/tsconfig.json と .nuxt/nuxt.d.ts を書き込む前に呼び出され、nuxt.d.ts にカスタム参照や宣言を追加したり、tsconfig.json のオプションを直接変更することができます。 |
listen | listenerServer, listener | 開発サーバーがロードされるときに呼び出されます。 |
schema:extend | schemas | デフォルトのスキーマを拡張することができます。 |
schema:resolved | schema | 解決されたスキーマを拡張することができます。 |
schema:beforeWrite | schema | 指定されたスキーマを書き込む前に呼び出されます。 |
schema:written | - | スキーマが書き込まれた後に呼び出されます。 |
vite:extend | viteBuildContext | Viteのデフォルトコンテキストを拡張することができます。 |
vite:extendConfig | viteInlineConfig, env | Viteのデフォルト設定を拡張することができます。 |
vite:configResolved | viteInlineConfig, env | 解決されたVite設定を読み取ることができます。 |
vite:serverCreated | viteServer, env | Viteサーバーが作成されたときに呼び出されます。 |
vite:compiled | - | Viteサーバーがコンパイルされた後に呼び出されます。 |
webpack:config | webpackConfigs | webpackコンパイラの設定前に呼び出されます。 |
webpack:configResolved | webpackConfigs | 解決されたwebpack設定を読み取ることができます。 |
webpack:compile | options | コンパイル直前に呼び出されます。 |
webpack:compiled | options | リソースがロードされた後に呼び出されます。 |
webpack:change | shortPath | WebpackBarの change 時に呼び出されます。 |
webpack:error | - | WebpackBarの done 時にエラーがある場合に呼び出されます。 |
webpack:done | - | WebpackBarの allDone 時に呼び出されます。 |
webpack:progress | statesArray | WebpackBarの progress 時に呼び出されます。 |
Nitroアプリフック(ランタイム、サーバーサイド)
利用可能なすべてのフックについては、Nitro を参照してください。
| フック | 引数 | 説明 | タイプ |
|---|---|---|---|
dev:ssr-logs | { path, logs } | サーバー | リクエストサイクルの終わりにサーバーサイドのログの配列と共に呼び出されます。 |
render:response | response, { event } | レスポンスを送信する前に呼び出されます。 | response, event |
render:html | html, { event } | HTMLを構築する前に呼び出されます。 | html, event |
render:island | islandResponse, { event, islandContext } | アイランドHTMLを構築する前に呼び出されます。 | islandResponse, event, islandContext |
close | - | Nitroが閉じられるときに呼び出されます。 | - |
error | error, { event? } | エラーが発生したときに呼び出されます。 | error, event |
request | event | リクエストが受信されたときに呼び出されます。 | event |
beforeResponse | event, { body } | レスポンスを送信する前に呼び出されます。 | event, unknown |
afterResponse | event, { body } | レスポンスを送信した後に呼び出されます。 | event, unknown |
tips
このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。
はじめに:Nuxtのライフサイクルフックがもたらすメリット
NuxtはVue.jsをベースにしたフレームワークであり、アプリケーションの構築を効率化するために多くの機能を提供しています。その中でも「ライフサイクルフック」は、アプリケーションの特定のタイミングで処理を差し込める強力な仕組みです。
このフックを活用することで、例えば以下のような課題を解決できます。
- アプリケーションの初期化処理や後処理を柔軟に実装したい
- エラー発生時の共通処理を一元管理したい
- SSR(サーバーサイドレンダリング)とCSR(クライアントサイドレンダリング)の境界で適切に処理を切り替えたい
- ページ遷移やデータフェッチのタイミングを細かく制御したい
Nuxtのライフサイクルフックは、単なるVueのライフサイクルとは異なり、Nuxt固有のイベントやビルド時のフックも含まれています。これにより、開発者はアプリケーションのあらゆるフェーズに介入でき、より高度なカスタマイズが可能になります。
まず結論:Nuxtライフサイクルフックの要点
-
多様なフックが用意されている
サーバー・クライアント両方のタイミングで呼ばれるものから、ビルド時に使うものまで幅広い。 -
用途に応じて使い分けることが重要
例えば、app:createdはVueアプリの初期化時、app:errorはエラー発生時、build:doneはビルド完了時に使う。 -
SSRとCSRの違いを意識する必要がある
フックが呼ばれる環境(サーバーかクライアントか)を理解しないと、意図しない動作やパフォーマンス低下を招く。 -
実務ではエラーハンドリング、データ更新、ページ遷移制御などで活用される
具体的なユースケースを知ることで、効果的にフックを利用できる。 -
注意点としてはHydrationの問題やパフォーマンスへの影響がある
不適切なフックの使い方は、SSRのHydrationエラーや不要な再レンダリングを引き起こす。
いつ使うべきか?使わない方がよいケース
使うべきケース
-
アプリケーションの初期化や終了処理をカスタマイズしたいとき
例:app:createdでグローバルなプラグインを登録、closeでリソース解放。 -
共通のエラーハンドリングを実装したいとき
例:app:errorでログ収集やユーザー通知を行う。 -
ページ遷移の開始・終了を検知してローディングUIを制御したいとき
例:page:startやpage:finishでローディングバーの表示・非表示。 -
ビルドプロセスに介入してカスタム処理を追加したいとき
例:build:beforeでビルド前のファイル生成や設定変更。 -
クライアント側で特定のタイミングに処理を差し込みたいとき
例:app:mountedでブラウザ固有の初期化処理を行う。
使わない方がよいケース
-
単純なコンポーネントのライフサイクル処理はVueの標準フックで十分な場合
Nuxtフックはグローバルかつアプリ全体に影響するため、局所的な処理には向かない。 -
パフォーマンスに影響を与える重い処理を頻繁に実行する場合
フックは頻繁に呼ばれることもあるため、処理負荷が高いとUXが悪化する。 -
SSRとCSRの違いを理解せずにクライアント専用の処理をサーバー側で実行しようとする場合
これによりHydrationエラーや不整合が発生する。
実務でよくあるユースケースとサンプルコード
1. グローバルエラーハンドリング
アプリ全体で発生するエラーを一括管理し、ログ送信やユーザー通知を行う例です。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('app:error', (err) => {
console.error('グローバルエラー:', err)
// 例: 外部サービスにエラーログを送信
sendErrorLog(err)
// ユーザー向けの通知処理もここで可能
})
})
2. ページ遷移時のローディング表示制御
ページの読み込み開始と終了を検知してローディングバーを表示・非表示にします。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => {
showLoadingBar()
})
nuxtApp.hook('page:finish', () => {
hideLoadingBar()
})
})
3. ビルド時にカスタムファイルを生成
ビルド前に特定の設定ファイルを自動生成する例です。
export default defineNuxtModule({
hooks: {
'build:before'() {
generateCustomConfigFile()
}
}
})
よくある落とし穴・注意点
SSRとCSRの環境差異に注意
Nuxtのフックはサーバー側とクライアント側の両方で呼ばれるものがあります。例えばapp:createdは両方で呼ばれますが、app:mountedはクライアントのみです。サーバーでしか動作しない処理やブラウザAPIを使う処理をサーバー側で実行するとエラーになります。
Hydrationエラーの原因に
サーバーでレンダリングしたHTMLとクライアントでの初期化処理が不一致だとHydrationエラーが発生します。フック内で状態を変更する場合は、サーバーとクライアントで同じ結果になるように注意しましょう。
パフォーマンスへの影響
頻繁に呼ばれるフック(例:page:startやpage:finish)で重い処理を行うと、ページ遷移のレスポンスが悪化します。必要最低限の処理に留め、非同期処理は可能な限り遅延させる工夫が必要です。
フックの同期性
vue:setupフックは同期的に実行される必要があります。非同期処理を入れるとNuxtの初期化が遅延し、予期せぬ挙動を招くため注意してください。
まとめ
Nuxtのライフサイクルフックは、アプリケーションのあらゆるフェーズに介入できる強力な機能です。初期化処理、エラーハンドリング、ページ遷移制御、ビルド時のカスタマイズなど、実務での活用範囲は広く、適切に使うことで開発効率と品質を大きく向上させられます。
ただし、SSRとCSRの違いやパフォーマンスへの影響を理解し、適切なフックを選択することが重要です。この記事で紹介したポイントやサンプルを参考に、Nuxtのフックを効果的に活用してください。
Nuxtの公式リポジトリやドキュメントで最新のフック一覧や使い方を随時確認することをおすすめします。フックはNuxtのバージョンアップに伴い追加・変更されることがあります。
title: 'Nuxt Nitroアプリフックの活用ガイド:サーバーサイド処理を自在に制御する方法' description: 'Nuxt Nitroのアプリフックはサーバーサイドの処理を柔軟にカスタマイズできる強力な機能です。本記事では、基本的な使い方から実務での活用例、注意点まで詳しく解説します。'
Nuxt Nitroアプリフックの活用ガイド
Nuxt 3 では、Nitro がサーバーサイドのランタイムとして動作し、さまざまなタイミングで処理をフックできる仕組みを提供しています。これにより、リクエストの受信からレスポンスの送信までの流れを自在にカスタマイズ可能です。
この補足記事では、公式ドキュメントで紹介されている Nitro アプリフックの概要を踏まえつつ、実務での具体的な活用方法や注意点を丁寧に解説します。サーバーサイドの挙動を細かく制御したい開発者にとって、理解しておくべき重要なポイントが詰まっています。
まず結論:Nitroアプリフックの要点
- Nitroアプリフックはサーバーサイドのリクエスト処理の各段階に介入できる仕組み
- 主なフックにはリクエスト受信時、レスポンス送信前後、HTML生成前などがある
- エラーハンドリングやログ収集、レスポンスの動的改変に活用可能
- 適切に使うことでカスタムAPIの実装やパフォーマンス最適化がしやすくなる
- ただしSSR/CSRの違いやHydrationの影響を理解しないと不具合の原因になる
いつ使うべきか・使わない方がよいケース
使うべきケース
-
サーバーサイドでのログ収集や監視を行いたいとき
例:dev:ssr-logsフックでリクエストごとのログをまとめて処理 -
レスポンスのヘッダーやボディを動的に変更したいとき
例:render:responseやbeforeResponseで認証トークンの付与やキャッシュ制御 -
HTMLの最終生成前にカスタム処理を挟みたいとき
例:render:htmlでSEO用のメタタグを動的に追加 -
APIのエラーハンドリングを一元化したいとき
例:errorフックで共通のエラーログ出力やレスポンス整形
使わない方がよいケース
-
クライアントサイドのUIロジックを制御したい場合
Nitroアプリフックはサーバーサイド専用なので、クライアント側の状態管理には不向きです。 -
単純なページ遷移やルーティング制御
これらはNuxtのページやミドルウェアで対応したほうがシンプルです。 -
パフォーマンスに過度な影響を与える重い処理
フック内で重い同期処理を行うとレスポンス遅延の原因になるため注意が必要です。
実務でよくあるユースケースとサンプルコード
1. リクエストごとのログ収集
サーバーに届いたリクエストの情報をログにまとめて処理したい場合、request フックを使います。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('request', (event) => {
console.log(`[Request] ${event.req.method} ${event.req.url}`)
})
})
2. レスポンス送信前にヘッダーを追加
APIレスポンスにカスタムヘッダーを付与したい場合は、beforeResponse フックが便利です。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('beforeResponse', (event) => {
event.res.setHeader('X-Custom-Header', 'MyValue')
})
})
3. HTML生成前にメタタグを動的挿入
SEO対策でページごとにメタタグを動的に変えたい場合、render:html フックを利用します。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
const title = event.req.url === '/' ? 'ホームページ' : 'その他ページ'
return html.replace(
'</head>',
`<title>${title}</title></head>`
)
})
})
よくある落とし穴・注意点
SSRとCSRの違いによる影響
Nitroアプリフックはサーバーサイドで動作するため、クライアント側の状態やライフサイクルとは独立しています。
そのため、フック内でクライアント固有の処理を期待すると動作しません。
Hydrationとの関係
サーバーで生成したHTMLとクライアントでのHydrationが不整合になると、UIの不具合や警告が発生します。
render:html などでHTMLを動的に書き換える際は、クライアント側のレンダリング結果と整合性が取れているか注意が必要です。
パフォーマンスへの影響
フック内で重い処理や同期的なブロッキング処理を行うと、レスポンス全体の遅延につながります。
可能な限り非同期処理を使い、処理時間を短く保つことが重要です。
エラーハンドリングの一元化
error フックはサーバーで発生した例外をキャッチできますが、適切にレスポンスを返さないとクライアントに不適切なエラーが伝わることがあります。
エラーレスポンスのフォーマットやログ出力は慎重に設計しましょう。
まとめ
NitroアプリフックはNuxt 3のサーバーサイド処理を自在にカスタマイズできる強力な機能です。
リクエストの受信からレスポンス送信までの各段階に介入できるため、ログ収集やレスポンス改変、エラーハンドリングなど多彩な用途に活用できます。
ただし、SSRとCSRの違いやHydrationの影響、パフォーマンス面の注意点を理解した上で使うことが重要です。
実務でのユースケースを踏まえ、適切にフックを活用すれば、より柔軟で高品質なNuxtアプリケーションの構築が可能になります。
NitroアプリフックはNuxtのプラグインとして実装します。defineNitroPlugin を使い、nitroApp.hooks.hook で各フックに登録する形が基本です。
※このページは Nuxt.js 公式ドキュメントの翻訳ページです。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/api/advanced/hooks