brand logo

ドキュメント

onPrehydrate

onPrehydrate を使用して、Nuxt がページをハイドレートする直前にクライアントでコールバックを実行します。

このコンポーザブルは Nuxt v3.12+ で利用可能です。

onPrehydrate は、Nuxt がページをハイドレートする直前にクライアントでコールバックを実行できるコンポーザブルライフサイクルフックです。

これは高度なユーティリティであり、注意して使用する必要があります。例えば、nuxt-time@nuxtjs/color-mode は、ハイドレーションの不一致を避けるために DOM を操作します。

使用法

onPrehydrate を Vue コンポーネントのセットアップ関数(例: <script> 内)やプラグインで呼び出します。これはサーバーで呼び出されたときにのみ効果があり、クライアントビルドには含まれません。

Signature
export function onPrehydrate(callback: (el: HTMLElement) => void): void
export function onPrehydrate(callback: string | ((el: HTMLElement) => void), key?: string): undefined | string

パラメータ

パラメータ必須説明
callback((el: HTMLElement) => void) | stringはいNuxt がハイドレートする前に実行する関数(または文字列化された関数)。HTML に文字列化されてインライン化されます。外部依存関係やコールバック外の変数を参照してはいけません。Nuxt ランタイムが初期化される前に実行されるため、Nuxt や Vue のコンテキストに依存してはいけません。
keystringいいえ(高度な)プレハイドレートスクリプトを識別するための一意のキー。複数のルートノードのような高度なシナリオで役立ちます。

戻り値

  • コールバック関数のみで呼び出された場合は undefined を返します。
  • コールバックとキーで呼び出された場合は文字列(プレハイドレート ID)を返し、高度な使用例で data-prehydrate-id 属性を設定またはアクセスするために使用できます。

app.vue
<script setup lang="ts">
declare const window: Window
// ---cut---
// Nuxt がハイドレートする前にコードを実行
onPrehydrate(() => {
  console.log(window)
})

// ルート要素にアクセス
onPrehydrate((el) => {
  console.log(el.outerHTML)
  // <div data-v-inspector="app.vue:15:3" data-prehydrate-id=":b3qlvSiBeH:"> Hi there </div>
})

// 高度な使用法: 自分で `data-prehydrate-id` にアクセス/設定
const prehydrateId = onPrehydrate((el) => {})
</script>

<template>
  <div>
    Hi there
  </div>
</template>

tips

このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。

onPrehydrateとは?イントロダクション

Nuxtアプリケーションでは、サーバーサイドレンダリング(SSR)によって生成されたHTMLをクライアント側でVueが「ハイドレーション」することで、インタラクティブなSPAとして動作を開始します。このハイドレーションの直前に処理を挟みたいケースは意外と多く、例えばDOMの微調整や外部スクリプトの初期化などが挙げられます。

onPrehydrate は、まさにこの「ハイドレーション直前」にクライアント側でコールバックを実行できるNuxtのライフサイクルフックです。これにより、ハイドレーションの不整合を防ぎつつ、必要な初期処理を安全に差し込むことが可能になります。

本記事では、onPrehydrate の基本的な使い方から、実務での具体的なユースケース、そして注意すべきポイントまで丁寧に解説します。初〜中級のNuxtユーザーが理解しやすいように、実践的な視点を交えて説明します。


まず結論:onPrehydrateの要点まとめ

  • ハイドレーション直前にクライアントで処理を実行できる
    SSRで生成されたHTMLがVueによってハイドレーションされる直前にコールバックを呼び出せる。

  • VueやNuxtのコンテキストに依存しない処理に適している
    ランタイム初期化前に実行されるため、VueのリアクティブAPIやNuxtのコンテキストは使えない。

  • DOM要素へのアクセスが可能
    コールバックにはハイドレーション対象のルートDOM要素が渡されるため、直接DOM操作もできる。

  • プラグインや<script>内で利用可能
    Vueコンポーネントのセットアップ関数やNuxtプラグインで呼び出せる。

  • 高度な用途では一意のキーを指定できる
    複数のルートノードがある場合などに、keyパラメータで識別子を付与可能。


いつ使うべきか?使わない方がよいケース

使うべきケース

  • ハイドレーションの不一致を防ぎたいとき
    例えば、クライアント側でのみ動的に変わる値をDOMに反映させたいが、Vueの初期化前に処理したい場合。

  • 外部ライブラリやカスタムスクリプトの初期化
    DOMがSSRで生成された状態のままのタイミングで、外部JSのセットアップを行いたいとき。

  • パフォーマンス最適化のための軽微なDOM操作
    ハイドレーション後に行うと再レンダリングが発生するような操作を事前に済ませたい場合。

使わない方がよいケース

  • VueのリアクティブAPIやNuxtのコンテキストが必要な処理
    onPrehydrateはランタイム初期化前に呼ばれるため、これらに依存する処理は動作しない。

  • 大規模なDOM操作や状態管理
    複雑なロジックはVueの通常のライフサイクルフック(onMountedなど)で行うべき。

  • クライアント専用の処理でハイドレーションとは無関係な場合
    例えばユーザー操作に応じた動的処理は、onPrehydrateではなく通常のクライアントサイドフックで十分。


実務でよくあるユースケースとサンプルコード

1. ハイドレーション不一致を防ぐためのスタイル調整

サーバーで生成されたHTMLとクライアントでの初期状態が異なると、Vueは警告を出したり再レンダリングを行います。onPrehydrateで事前にDOMを調整することでこれを防げます。

<script setup lang="ts">
onPrehydrate((el) => {
  // 例: クライアント環境でのみ適用したいスタイルを事前にセット
  const specialElement = el.querySelector('.dynamic-style')
  if (specialElement) {
    specialElement.style.color = 'blue'
  }
})
</script>

<template>
  <div>
    <p class="dynamic-style">このテキストは青色になります</p>
  </div>
</template>

2. 外部ライブラリの初期化をハイドレーション前に行う

例えば、カラーモード切替や日時表示のライブラリがハイドレーション時の不整合を起こす場合、onPrehydrateで初期化処理を差し込むと安定します。

onPrehydrate(() => {
  // windowオブジェクトが利用可能なタイミングで外部スクリプトの初期化
  if (window && window.someExternalLib) {
    window.someExternalLib.init()
  }
})

3. 複数ルートノードを持つコンポーネントでの識別子利用

複雑なレイアウトで複数のルートDOMがある場合、keyを使って特定のハイドレーション処理を区別できます。

<script setup lang="ts">
const id = onPrehydrate((el) => {
  console.log('Prehydrate element:', el)
}, 'unique-key')

console.log('Prehydrate ID:', id)
</script>

<template>
  <div>ルートノード1</div>
  <div>ルートノード2</div>
</template>

よくある落とし穴・注意点

1. VueやNuxtのコンテキストに依存しないこと

onPrehydrateはNuxtやVueのランタイムがまだ初期化されていない段階で実行されるため、useRouteruseStateなどのAPIは使えません。これらを使うとエラーになるか、意図しない動作になります。

2. DOM操作は最小限に

ハイドレーション直前のDOM操作は慎重に行いましょう。過度な操作はパフォーマンス低下やハイドレーションの失敗を招く恐れがあります。

3. SSRとCSRの差異に注意

サーバーで生成されたHTMLとクライアントでの初期状態が異なると、VueはHydration mismatch(不一致)を警告します。onPrehydrateはこの不一致を防ぐための手段ですが、根本的な原因を解決することが重要です。

4. 外部依存関係の取り扱い

コールバック内で外部変数や依存関係を参照すると、文字列化された関数としてインライン化される際に問題が発生します。コールバックは純粋な関数として書き、外部状態に依存しないようにしましょう。


まとめ

onPrehydrateはNuxtのSSRとクライアントの橋渡しをするハイドレーション直前に処理を挟める強力なフックです。ハイドレーションの不一致を防いだり、外部ライブラリの初期化を安全に行うのに役立ちます。

ただし、VueやNuxtのコンテキストに依存できないため、使いどころを見極めることが重要です。実務では軽微なDOM操作や外部スクリプトのセットアップに限定して使うのが無難です。

正しく活用すれば、Nuxtアプリのパフォーマンスと安定性を向上させる強力なツールとなるでしょう。


onPrehydrateはNuxt v3.12以降で利用可能です。古いバージョンでは使えないため、バージョンを確認してから導入してください。