brand logo

ドキュメント

NuxtApp

Nuxtでは、コンポーザブル、コンポーネント、プラグイン内でランタイムアプリケーションコンテキストにアクセスできます。

Nuxtでは、コンポーザブル、コンポーネント、プラグイン内でランタイムアプリケーションコンテキストにアクセスできます。

こちらも参照 v2.nuxt.com > docs > internals-glossary > context

Nuxt App インターフェース

こちらも参照 guide > going-further > internals#the-nuxtapp-interface

Nuxt コンテキスト

多くの組み込みおよびユーザー作成のコンポーザブルやユーティリティは、Nuxtインスタンスへのアクセスを必要とする場合があります。これはアプリケーションのどこにでも存在するわけではなく、リクエストごとに新しいインスタンスが作成されます。

現在、NuxtコンテキストはプラグインNuxtフックNuxtミドルウェアdefineNuxtRouteMiddlewareでラップされている場合)、およびセットアップ関数(ページやコンポーネント内)でのみアクセス可能です。

コンテキストへのアクセスなしにコンポーザブルが呼び出された場合、「Nuxtインスタンスへのアクセスを必要とするコンポーザブルがプラグイン、Nuxtフック、Nuxtミドルウェア、またはVueセットアップ関数の外で呼び出されました」というエラーが発生することがあります。その場合、nuxtApp.runWithContextを使用して、このコンテキスト内で関数を明示的に呼び出すこともできます。

NuxtAppへのアクセス

コンポーザブル、プラグイン、コンポーネント内では、useNuxtApp()を使用してnuxtAppにアクセスできます:

composables/useMyComposable.ts
export function useMyComposable () {
  const nuxtApp = useNuxtApp()
  // ランタイムのnuxtアプリインスタンスにアクセス
}

コンポーザブルが常にnuxtAppを必要としない場合や、存在するかどうかを確認したい場合、useNuxtAppが例外をスローするため、代わりにtryUseNuxtAppを使用できます。

プラグインもまた、便宜上、最初の引数としてnuxtAppを受け取ります。

こちらも参照 guide > directory-structure > plugins

ヘルパーの提供

すべてのコンポーザブルやアプリケーションで使用可能なヘルパーを提供できます。これは通常、Nuxtプラグイン内で行われます。

const nuxtApp = useNuxtApp()
nuxtApp.provide('hello', (name) => `Hello ${name}!`)

console.log(nuxtApp.$hello('name')) // "Hello name!"と表示されます
こちらも参照 guide > directory-structure > plugins#providing-helpers こちらも参照 v2.nuxt.com > docs > directory-structure > plugins

tips

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

NuxtAppとは?何が嬉しいのか

NuxtAppは、Nuxt 3で導入されたランタイムのアプリケーションコンテキストを表す仕組みです。これにより、コンポーネントやプラグイン、コンポーザブルの中からアプリケーション全体の状態や機能にアクセスできるようになります。

従来のNuxt 2での「Nuxtコンテキスト」に相当しますが、Nuxt 3ではより型安全かつ柔軟に設計されており、開発者はアプリケーションの状態管理やプラグインの注入、API呼び出しの共通化などを効率的に行えます。

特に、以下のような課題を解決します。

  • アプリケーション全体で共通の機能や状態を簡単に共有したい
  • プラグインやコンポーザブルからNuxtの内部APIに安全にアクセスしたい
  • SSR(サーバーサイドレンダリング)とCSR(クライアントサイドレンダリング)で一貫した動作を実現したい

まず結論:NuxtAppのポイント

  • useNuxtApp()で現在のNuxtアプリケーションインスタンスにアクセス可能
  • プラグインでは第一引数としてnuxtAppが渡されるため、直接利用できる
  • nuxtApp.provide()でヘルパー関数や値を全体に注入できる
  • コンポーザブルやミドルウェア、プラグイン、セットアップ関数内でのみ安全に利用可能
  • tryUseNuxtApp()を使うと、存在しない場合に例外を避けて安全にアクセスできる

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

使うべきケース

  • 複数のコンポーネントやプラグインで共通の機能を共有したいとき
  • プラグインで外部ライブラリやAPIクライアントを注入し、どこからでも使いたいとき
  • SSRとCSRの両方で同じ状態や機能を扱いたいとき
  • Nuxtの内部API(ルーター、ストア、i18nなど)にアクセスしたいとき

使わない方がよいケース

  • 単純なローカルな状態管理だけで完結する場合(Vueのrefreactiveで十分)
  • NuxtAppに依存しない純粋なユーティリティ関数やロジック
  • コンポーネント外でNuxtAppが存在しない環境(例:純粋なユニットテストやビルド時処理)での利用

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

1. プラグインでAPIクライアントを注入する

// plugins/apiClient.ts
import { defineNuxtPlugin } from '#app'
import axios from 'axios'

export default defineNuxtPlugin((nuxtApp) => {
  const apiClient = axios.create({
    baseURL: 'https://api.example.com'
  })

  nuxtApp.provide('apiClient', apiClient)
})

コンポーネントやコンポーザブルで利用する例:

export function useApi() {
  const nuxtApp = useNuxtApp()
  const apiClient = nuxtApp.$apiClient

  const fetchData = async () => {
    const response = await apiClient.get('/data')
    return response.data
  }

  return { fetchData }
}

2. コンポーザブル内でNuxtAppの機能を利用する

export function useAuth() {
  const nuxtApp = useNuxtApp()
  const user = ref(null)

  const login = async (credentials) => {
    const { data } = await nuxtApp.$apiClient.post('/login', credentials)
    user.value = data.user
  }

  return { user, login }
}

3. ミドルウェアでNuxtAppを使った認証チェック

export default defineNuxtRouteMiddleware((to, from) => {
  const nuxtApp = useNuxtApp()
  const user = nuxtApp.$authUser

  if (!user) {
    return navigateTo('/login')
  }
})

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

1. NuxtAppは特定のコンテキスト内でのみ有効

useNuxtApp()はプラグイン、ミドルウェア、セットアップ関数、コンポーザブルの中でのみ安全に呼び出せます。これ以外の場所で呼ぶと例外が発生します。

もしコンポーザブルが必ずしもNuxtAppを必要としない場合は、tryUseNuxtApp()を使い、存在しない場合はフォールバック処理を行いましょう。

2. SSRとCSRでの状態管理に注意

NuxtAppはリクエストごとに新しいインスタンスが作られるため、サーバー側での状態はリクエスト単位で分離されています。クライアント側での状態と混同しないようにしましょう。

グローバルな状態管理はPiniaやVuexなどのストアを使うのが適切です。

3. パフォーマンスへの影響

NuxtAppに大量のデータや重い処理を注入すると、アプリケーションの起動やレンダリングに影響が出る可能性があります。必要最低限の機能だけを提供し、重い処理は遅延ロードや非同期処理に分けることをおすすめします。

まとめ

NuxtAppはNuxt 3の中核的な仕組みであり、アプリケーションのあらゆる部分から共通機能や状態にアクセスできる強力なツールです。プラグインやコンポーザブルでの活用により、コードの再利用性や保守性が大きく向上します。

ただし、利用できるコンテキストが限られていることやSSR/CSRの違いによる状態管理の注意点を理解し、適切に使い分けることが重要です。

NuxtAppを正しく活用して、より効率的で拡張性の高いNuxtアプリケーション開発を目指しましょう。

NuxtAppの機能を拡張したい場合は、プラグインでnuxtApp.provide()を活用して独自のヘルパーを注入するのが便利です。これにより、どこからでも簡単に共通機能を呼び出せます。