brand logo

ドキュメント

$fetch

Nuxtは、HTTPリクエストを行うための$fetchヘルパーをグローバルに公開するためにofetchを使用します。

Nuxtは、ofetchを使用して、VueアプリやAPIルート内でHTTPリクエストを行うための$fetchヘルパーをグローバルに公開します。

サーバーサイドレンダリング中に、内部のAPIルートを取得するために$fetchを呼び出すと、関連する関数を直接呼び出し(リクエストをエミュレート)、追加のAPIコールを節約します。

コンポーネント内で$fetchuseAsyncDataでラップせずに使用すると、データが二重に取得されます:最初はサーバーで、次にクライアントサイドでのハイドレーション中に再度取得されます。これは、$fetchがサーバーからクライアントへの状態を転送しないためです。したがって、クライアントはデータを再度取得する必要があるため、両方の側でフェッチが実行されます。

使用法

コンポーネントデータを取得する際に二重のデータフェッチを防ぐために、useFetchまたはuseAsyncData + $fetchを使用することをお勧めします。

app.vue
// SSR中、データはサーバーとクライアントの両方で二重にフェッチされます。
const dataTwice = await $fetch('/api/item')

// SSR中、データはサーバー側でのみフェッチされ、クライアントに転送されます。
const { data } = await useAsyncData('item', () => $fetch('/api/item'))

// useAsyncData + $fetchのショートカットとしてuseFetchを使用することもできます
const { data } = await useFetch('/api/item')
こちらも参照 getting-started > data-fetching

$fetchは、クライアントサイドでのみ実行されるメソッドで使用できます。

pages/contact.vue
<script setup lang="ts">
async function contactForm() {
  await $fetch('/api/contact', {
    method: 'POST',
    body: { hello: 'world '}
  })
}
</script>

<template>
  <button @click="contactForm">Contact</button>
</template>

$fetchは、Nuxt 2用に作られた@nuxt/http@nuxtjs/axiosの代わりに、NuxtでHTTPコールを行うための推奨方法です。

開発中に自己署名証明書を使用して外部のHTTPS URLを呼び出すために$fetchを使用する場合、環境にNODE_TLS_REJECT_UNAUTHORIZED=0を設定する必要があります。

ヘッダーとクッキーの送信

ブラウザで$fetchを呼び出すと、cookieのようなユーザーヘッダーがAPIに直接送信されます。

しかし、サーバーサイドレンダリング中は、サーバーサイドリクエストフォージェリ(SSRF)認証の誤用などのセキュリティリスクのため、$fetchはユーザーのブラウザクッキーを含まず、フェッチレスポンスからのクッキーも渡しません。

// これはSSR中にヘッダーやクッキーを転送しません
const { data } = await useAsyncData(() => $fetch('/api/cookies'))

サーバーでヘッダーとクッキーを転送する必要がある場合は、手動でそれらを渡す必要があります:

pages/index.vue
// これはユーザーのヘッダーとクッキーを`/api/cookies`に転送します
const requestFetch = useRequestFetch()
const { data } = await useAsyncData(() => requestFetch('/api/cookies'))

しかし、サーバー上で相対URLを使用してuseFetchを呼び出すと、NuxtはuseRequestFetchを使用してヘッダーとクッキーをプロキシします(hostのような転送されるべきでないヘッダーを除く)。

tips

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

$fetchの活用と注意点:Nuxtでの効率的なHTTPリクエスト管理

Nuxtが提供する$fetchは、HTTPリクエストを簡潔かつ効率的に行うためのグローバルヘルパーです。内部的には軽量で高速なofetchを利用しており、VueコンポーネントやAPIルートからシームレスにデータ取得が可能です。

この補足記事では、$fetchの基本的な使い方だけでなく、実務での活用シーンやよくある落とし穴、パフォーマンス面での注意点まで丁寧に解説します。Nuxtでのデータフェッチをより理解し、最適化したい初〜中級者の方に役立つ内容です。


まず結論:$fetchのポイントまとめ

  • $fetchofetchをベースにした軽量なHTTPクライアントで、Nuxtでグローバルに利用可能
  • サーバーサイドレンダリング(SSR)中にAPIルートを呼ぶと、内部関数を直接呼び出しAPIコールを節約できる
  • ただし、コンポーネント内で直接$fetchを使うと、SSRとクライアントで二重にデータ取得が発生するため注意が必要
  • 二重取得を防ぐにはuseFetchuseAsyncDataと組み合わせて使うのが推奨
  • SSR中はユーザーのクッキーやヘッダーは自動で送信されないため、必要に応じて手動で転送する必要がある
  • クライアントサイドでのPOSTリクエストや外部API呼び出しにも適している

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

使うべきケース

  • APIルートや外部APIからのデータ取得
    軽量でシンプルなHTTPリクエストが必要なときに最適。特にNuxtのAPIルートを呼ぶ場合はSSR中に内部呼び出しができるため効率的。

  • クライアントサイドでの非同期通信
    フォーム送信やユーザー操作に応じたAPI呼び出しに便利。

  • SSRとCSRの両方でデータを扱う場合
    useFetchuseAsyncDataと組み合わせて使うことで、サーバーで取得したデータをクライアントに引き継げる。

使わない方がよいケース

  • コンポーネント内で直接$fetchを使う場合
    SSRとCSRで二重にフェッチされてしまい、パフォーマンス低下や不要なAPIコールが発生する。

  • 認証情報やユーザー固有のヘッダーを自動で送信したい場合
    SSR中は自動でクッキーやヘッダーが送信されないため、手動で転送処理を実装しないと認証が機能しない。


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

1. SSR中にAPIルートからデータを効率的に取得

<script setup lang="ts">
// useAsyncDataと組み合わせてサーバー側でのみデータを取得し、クライアントに転送
const { data, pending, error } = await useAsyncData('posts', () => $fetch('/api/posts'))
</script>

<template>
  <div v-if="pending">読み込み中...</div>
  <div v-else-if="error">エラーが発生しました</div>
  <ul v-else>
    <li v-for="post in data" :key="post.id">{{ post.title }}</li>
  </ul>
</template>

この方法なら、SSR時にAPIコールを1回だけ行い、クライアント側で再取得されることを防げます。


2. クライアントサイドでのフォーム送信

<script setup lang="ts">
async function submitContact() {
  await $fetch('/api/contact', {
    method: 'POST',
    body: { name: '山田太郎', message: 'お問い合わせ内容' }
  })
  alert('送信が完了しました')
}
</script>

<template>
  <button @click="submitContact">送信</button>
</template>

ユーザー操作に応じて非同期にAPIへPOSTリクエストを送る際に便利です。


3. SSR中にユーザーのクッキーをAPIに転送したい場合

// useRequestFetchを使うとSSR中にヘッダーやクッキーを自動転送可能
const requestFetch = useRequestFetch()
const { data } = await useAsyncData(() => requestFetch('/api/user/profile'))

ユーザー認証が必要なAPI呼び出しで、SSR中にクッキーを含めてリクエストしたい場合に有効です。


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

1. SSRとCSRでの二重フェッチ

コンポーネント内で直接$fetchを使うと、SSR時にサーバーで取得した後、クライアントのハイドレーション時に再度フェッチが走ります。これは$fetchがサーバーからクライアントへの状態を自動で引き継がないためです。

対策
必ずuseFetchuseAsyncDataでラップし、サーバーで取得したデータをクライアントにシリアライズして渡しましょう。


2. SSR中のヘッダー・クッキーの扱い

SSR中はセキュリティ上の理由から、$fetchはユーザーのブラウザクッキーや認証ヘッダーを自動で送信しません。これにより、認証が必要なAPI呼び出しが失敗することがあります。

対策
useRequestFetchを使うか、明示的にヘッダーやクッキーを取得してリクエストに含める実装が必要です。


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

  • 不必要な二重フェッチはAPIサーバーへの負荷増加やページの初期表示遅延を招きます。
  • SSR中に外部APIを呼ぶ場合はレスポンス時間がページ表示速度に直結するため、キャッシュや遅延読み込みの検討が重要です。

まとめ

Nuxtの$fetchは、軽量で使いやすいHTTPリクエストヘルパーとして非常に便利ですが、SSRとCSRの特性を理解し適切に使うことが重要です。特にデータの二重取得や認証情報の扱いには注意が必要です。

  • SSR中はuseFetchuseAsyncDataと組み合わせて使う
  • 認証が必要なAPI呼び出しはuseRequestFetchでヘッダーを転送する
  • クライアントサイドの非同期通信には直接$fetchを活用する

これらを踏まえて活用すれば、Nuxtアプリのデータ取得を効率化し、パフォーマンスとセキュリティを両立できます。


$fetchはNuxt 2の@nuxt/http@nuxtjs/axiosの推奨代替として設計されており、最新のNuxt 3環境でのHTTP通信に最適化されています。