brand logo

ドキュメント

useFetch

SSRに優しいComposableでAPIエンドポイントからデータを取得します。

このComposableは、useAsyncData$fetchの便利なラッパーを提供します。URLとフェッチオプションに基づいてキーを自動生成し、サーバールートに基づいてリクエストURLの型ヒントを提供し、APIレスポンスタイプを推測します。

useFetchは、セットアップ関数、プラグイン、またはルートミドルウェアで直接呼び出すことを意図したComposableです。リアクティブなComposableを返し、ページがハイドレートされる際にクライアント側でデータを再フェッチすることなく、サーバーからクライアントにレスポンスを渡すためにNuxtペイロードにレスポンスを追加する処理を行います。

使用法

pages/modules.vue
const { data, status, error, refresh, clear } = await useFetch('/api/modules', {
  pick: ['title']
})

カスタムのuseFetchラッパーを使用している場合、Composable内でそれをawaitしないでください。予期しない動作を引き起こす可能性があります。カスタム非同期データフェッチャーの作成方法についてはこのレシピを参照してください。

datastatuserrorはVueのrefであり、<script>内で使用する際には.valueでアクセスする必要があります。一方、refresh/executeclearは通常の関数です。

queryオプションを使用すると、クエリに検索パラメータを追加できます。このオプションはunjs/ofetchから拡張されており、URLの作成にはunjs/ufoを使用しています。オブジェクトは自動的に文字列化されます。

const param1 = ref('value1')
const { data, status, error, refresh } = await useFetch('/api/modules', {
  query: { param1, param2: 'value2' }
})

上記の例はhttps://api.nuxt.com/modules?param1=value1&param2=value2となります。

また、インターセプターを使用することもできます:

const { data, status, error, refresh, clear } = await useFetch('/api/auth/login', {
  onRequest({ request, options }) {
    // リクエストヘッダーを設定
    // これはofetch >= 1.4.0に依存していることに注意 - ロックファイルを更新する必要があるかもしれません
    options.headers.set('Authorization', '...')
  },
  onRequestError({ request, options, error }) {
    // リクエストエラーを処理
  },
  onResponse({ request, response, options }) {
    // レスポンスデータを処理
    localStorage.setItem('token', response._data.token)
  },
  onResponseError({ request, response, options }) {
    // レスポンスエラーを処理
  }
})

リアクティブキーと共有状態

URLとしてcomputed refまたは通常のrefを使用することで、URLが変更されると自動的に更新される動的なデータフェッチが可能です:

pages/[id\
const route = useRoute()
const id = computed(() => route.params.id)

// ルートが変更されidが更新されると、データは自動的に再フェッチされます
const { data: post } = await useFetch(() => `/api/posts/${id.value}`)

同じURLとオプションで複数のコンポーネントでuseFetchを使用する場合、それらは同じdataerrorstatusのrefを共有します。これにより、コンポーネント間での一貫性が確保されます。

useFetchはコンパイラによって変換される予約関数名であるため、自分の関数をuseFetchと名付けないでください。

useFetchからデストラクトされたdata変数が文字列であり、JSON解析されたオブジェクトでない場合は、コンポーネントにimport { useFetch } from '@vueuse/core'のようなインポート文が含まれていないことを確認してください。

こちらも参照 getting-started > data-fetching

Signature
function useFetch<DataT, ErrorT>(
  url: string | Request | Ref<string | Request> | (() => string | Request),
  options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT, ErrorT>>

type UseFetchOptions<DataT> = {
  key?: string
  method?: string
  query?: SearchParams
  params?: SearchParams
  body?: RequestInit['body'] | Record<string, any>
  headers?: Record<string, string> | [key: string, value: string][] | Headers
  baseURL?: string
  server?: boolean
  lazy?: boolean
  immediate?: boolean
  getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
  deep?: boolean
  dedupe?: 'cancel' | 'defer'
  default?: () => DataT
  transform?: (input: DataT) => DataT | Promise<DataT>
  pick?: string[]
  watch?: WatchSource[] | false
}

type AsyncDataRequestContext = {
  /** このデータリクエストの理由 */
  cause: 'initial' | 'refresh:manual' | 'refresh:hook' | 'watch'
}

type AsyncData<DataT, ErrorT> = {
  data: Ref<DataT | null>
  refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>
  execute: (opts?: AsyncDataExecuteOptions) => Promise<void>
  clear: () => void
  error: Ref<ErrorT | null>
  status: Ref<AsyncDataRequestStatus>
}

interface AsyncDataExecuteOptions {
  dedupe?: 'cancel' | 'defer'
}

type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'

パラメータ

  • URL (string | Request | Ref<string> | () => string | Request): フェッチするURLまたはリクエスト。文字列、Requestオブジェクト、Vueのref、または文字列/Requestを返す関数で指定可能。動的エンドポイントのリアクティビティをサポート。

  • options (object): フェッチリクエストの設定。unjs/ofetchオプションとAsyncDataOptionsを拡張。すべてのオプションは静的値、ref、またはcomputed値にできる。

オプションデフォルト説明
keystring自動生成重複排除のためのユニークキー。指定しない場合、URLとオプションから生成されます。
methodstring'GET'HTTPリクエストメソッド。
queryobject-URLに追加するクエリ/検索パラメータ。エイリアス: params。ref/computedをサポート。
paramsobject-queryのエイリアス。
bodyRequestInit['body'] | Record<string,>-リクエストボディ。オブジェクトは自動的に文字列化されます。ref/computedをサポート。
headersRecord<string,> | [key, value][] | Headers-リクエストヘッダー。
baseURLstring-リクエストのベースURL。
timeoutnumber-リクエストを中止するまでのタイムアウト(ミリ秒)。
cacheboolean | string-キャッシュ制御。Booleanでキャッシュを無効化、またはFetch APIの値を使用: default, no-storeなど。
serverbooleantrueサーバーでフェッチするかどうか。
lazybooleanfalsetrueの場合、ルートがロードされた後に解決(ナビゲーションをブロックしない)。
immediatebooleantruefalseの場合、リクエストが即座に発火するのを防ぎます。
default() => DataT-非同期解決前のdataのデフォルト値のファクトリー。
transform(input: DataT) => DataT | Promise<DataT>-解決後の結果を変換する関数。
getCachedData(key, nuxtApp, ctx) => DataT | undefined-キャッシュされたデータを返す関数。デフォルトは以下を参照。
pickstring[]-結果から指定されたキーのみを選択。
watchWatchSource[] | false-リアクティブなソースの配列を監視して自動リフレッシュ。falseで監視を無効化。
deepbooleanfalseデータを深いrefオブジェクトで返す。
dedupe'cancel' | 'defer''cancel'同じキーを一度に複数回フェッチしないようにする。
$fetchtypeof $fetch-カスタム$fetch実装。

すべてのフェッチオプションはcomputedまたはref値を与えることができます。これらは監視され、更新されると新しいリクエストが自動的に行われます。

getCachedDataのデフォルト:

const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating 
 ? nuxtApp.payload.data[key] 
 : nuxtApp.static.data[key]

これはnuxt.configexperimental.payloadExtractionが有効な場合にのみデータをキャッシュします。

戻り値

名前説明
dataRef<DataT | null>非同期フェッチの結果。
refresh(opts?: AsyncDataExecuteOptions) => Promise<void>データを手動でリフレッシュするための関数。デフォルトでは、Nuxtはrefreshが終了するまで再実行を待ちます。
execute(opts?: AsyncDataExecuteOptions) => Promise<void>refreshのエイリアス。
errorRef<ErrorT | null>データフェッチが失敗した場合のエラーオブジェクト。
statusRef<'idle'>データリクエストのステータス。可能な値は以下を参照。
clear() => voiddataundefined(または提供された場合はoptions.default()の値)にリセットし、errornullに設定し、statusidleに設定し、保留中のリクエストをキャンセルします。

ステータス値

  • idle: リクエストが開始されていない(例: { immediate: false }またはサーバーレンダリングで{ server: false }
  • pending: リクエストが進行中
  • success: リクエストが正常に完了
  • error: リクエストが失敗

サーバーでデータをフェッチしていない場合(例えば、server: falseを使用している場合)、データはハイドレーションが完了するまでフェッチされません。つまり、クライアントサイドでuseFetchをawaitしても、<script>内ではdataはnullのままです。

サンプルコードの編集とプレビューexamples > advanced > use-custom-fetch-composable
サンプルコードの編集とプレビューexamples > features > data-fetching

tips

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

NuxtのuseFetchとは?〜何が嬉しいのか〜

NuxtのuseFetchは、サーバーサイドレンダリング(SSR)とクライアントサイドレンダリング(CSR)の両方に対応したデータ取得用のComposableです。APIからのデータ取得を簡潔に書けるだけでなく、サーバーで取得したデータをクライアントに効率よく引き継ぐため、ページの初期表示が高速化されます。

従来のAPI呼び出しでは、サーバーとクライアントで別々にデータを取得する必要があり、二重フェッチや表示のちらつきが発生しやすい問題がありました。useFetchはこれらの課題を解決し、開発者がシンプルに非同期データを扱えるように設計されています。


まず結論:useFetchのポイント

  • SSR対応:サーバーでデータを取得し、クライアントにハイドレーション時に再フェッチさせない
  • リアクティブなURL指定refcomputedを使い動的にAPIエンドポイントを変更可能
  • 自動キャッシュと重複排除:同じキーのリクエストは一度だけ実行し、結果を共有
  • 豊富なオプション:クエリパラメータ、ヘッダー設定、リクエストインターセプターなど細かく制御可能
  • 手動リフレッシュrefresh関数で必要に応じてデータを再取得できる
  • エラーハンドリングが簡単errorのrefでエラー状態を管理可能

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

使うべきケース

  • SSR対応のAPIデータ取得が必要なページやコンポーネント
  • ページロード時に初期データをサーバーで取得し、クライアントで再利用したい場合
  • APIエンドポイントが動的に変わる場合(例:ルートパラメータに応じて)
  • 複数コンポーネント間で同じデータを共有したい場合
  • APIリクエストに細かい制御(ヘッダー設定やインターセプター)が必要な場合

使わない方がよいケース

  • 完全にクライアントサイドでのみ動作する軽量なデータ取得(単純なfetchやaxiosで十分)
  • ページの初期表示にデータが不要で、ユーザー操作後にのみ取得する場合(lazyオプションを使うか別手段を検討)
  • 非同期処理の制御が複雑で、useFetchの自動管理が合わない場合(カスタムComposableを検討)

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

1. ルートパラメータに応じた動的データ取得

import { computed } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const userId = computed(() => route.params.id)

const { data: user, error, refresh } = await useFetch(() => `/api/users/${userId.value}`)

この例では、URLパラメータidが変わるたびに自動でAPIを再フェッチし、最新のユーザーデータを取得します。

2. 認証トークンを付与したAPIリクエスト

const { data, error } = await useFetch('/api/profile', {
  onRequest({ options }) {
    options.headers.set('Authorization', `Bearer ${localStorage.getItem('token')}`)
  }
})

API呼び出し時にヘッダーを動的に設定し、認証が必要なエンドポイントに対応します。

3. 手動でデータをリフレッシュするケース

const { data, refresh, status } = await useFetch('/api/posts')

function reloadPosts() {
  refresh()
}

ユーザーの操作に応じて最新データを取得したい場合にrefreshを呼び出します。


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

SSRとCSRのハイドレーションの違いに注意

useFetchはサーバーで取得したデータをNuxtのペイロードに含め、クライアントで再フェッチを防ぎます。しかし、server: falseを指定するとサーバーでの取得がスキップされ、クライアントでのみフェッチされるため、初期表示時にdatanullのままになることがあります。

リアクティブなURLの扱い

URLをrefcomputedで渡す場合、URLが変わるたびに自動で再フェッチされます。意図しない頻繁なリクエストを防ぐため、監視対象の値が安定しているか確認しましょう。

重複リクエストの制御

同じキーのリクエストはデフォルトで重複排除されますが、dedupeオプションで挙動を制御可能です。複数コンポーネントで同じデータを共有したい場合は便利ですが、異なるパラメータでのリクエストが混ざらないようキーの指定に注意してください。

パフォーマンスへの影響

大量のuseFetchを同時に使うとリクエストが集中し、パフォーマンス低下やAPI制限にかかる可能性があります。必要に応じてlazyオプションや監視の無効化を検討しましょう。


まとめ

NuxtのuseFetchはSSRに最適化された強力なデータ取得Composableであり、APIからのデータ取得を効率的かつ簡潔に実装できます。リアクティブなURL指定やリクエストインターセプターなど柔軟な機能を備え、実務での多様なユースケースに対応可能です。

ただし、SSRとCSRの挙動の違いや重複リクエストの制御など、理解しておくべきポイントも多いため、この記事で紹介した注意点を踏まえて適切に使いこなしてください。これにより、Nuxtアプリケーションのパフォーマンスとユーザー体験を大きく向上させることができます。

useFetchuseAsyncData$fetchの便利なラッパーです。公式ドキュメントと合わせて使い方を理解すると、より高度なデータ取得ロジックも実装しやすくなります。