$fetch
Nuxtは、HTTPリクエストを行うための$fetchヘルパーをグローバルに公開するためにofetchを使用します。
Nuxtは、ofetchを使用して、VueアプリやAPIルート内でHTTPリクエストを行うための$fetchヘルパーをグローバルに公開します。
サーバーサイドレンダリング中に、内部のAPIルートを取得するために$fetchを呼び出すと、関連する関数を直接呼び出し(リクエストをエミュレート)、追加のAPIコールを節約します。
コンポーネント内で$fetchをuseAsyncDataでラップせずに使用すると、データが二重に取得されます:最初はサーバーで、次にクライアントサイドでのハイドレーション中に再度取得されます。これは、$fetchがサーバーからクライアントへの状態を転送しないためです。したがって、クライアントはデータを再度取得する必要があるため、両方の側でフェッチが実行されます。
使用法
コンポーネントデータを取得する際に二重のデータフェッチを防ぐために、useFetchまたはuseAsyncData + $fetchを使用することをお勧めします。
// 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')$fetchは、クライアントサイドでのみ実行されるメソッドで使用できます。
<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'))サーバーでヘッダーとクッキーを転送する必要がある場合は、手動でそれらを渡す必要があります:
// これはユーザーのヘッダーとクッキーを`/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のポイントまとめ
$fetchはofetchをベースにした軽量なHTTPクライアントで、Nuxtでグローバルに利用可能- サーバーサイドレンダリング(SSR)中にAPIルートを呼ぶと、内部関数を直接呼び出しAPIコールを節約できる
- ただし、コンポーネント内で直接
$fetchを使うと、SSRとクライアントで二重にデータ取得が発生するため注意が必要 - 二重取得を防ぐには
useFetchやuseAsyncDataと組み合わせて使うのが推奨 - SSR中はユーザーのクッキーやヘッダーは自動で送信されないため、必要に応じて手動で転送する必要がある
- クライアントサイドでのPOSTリクエストや外部API呼び出しにも適している
いつ使うべきか・使わない方がよいケース
使うべきケース
-
APIルートや外部APIからのデータ取得
軽量でシンプルなHTTPリクエストが必要なときに最適。特にNuxtのAPIルートを呼ぶ場合はSSR中に内部呼び出しができるため効率的。 -
クライアントサイドでの非同期通信
フォーム送信やユーザー操作に応じたAPI呼び出しに便利。 -
SSRとCSRの両方でデータを扱う場合
useFetchやuseAsyncDataと組み合わせて使うことで、サーバーで取得したデータをクライアントに引き継げる。
使わない方がよいケース
-
コンポーネント内で直接
$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がサーバーからクライアントへの状態を自動で引き継がないためです。
対策
必ずuseFetchやuseAsyncDataでラップし、サーバーで取得したデータをクライアントにシリアライズして渡しましょう。
2. SSR中のヘッダー・クッキーの扱い
SSR中はセキュリティ上の理由から、$fetchはユーザーのブラウザクッキーや認証ヘッダーを自動で送信しません。これにより、認証が必要なAPI呼び出しが失敗することがあります。
対策
useRequestFetchを使うか、明示的にヘッダーやクッキーを取得してリクエストに含める実装が必要です。
3. パフォーマンスへの影響
- 不必要な二重フェッチはAPIサーバーへの負荷増加やページの初期表示遅延を招きます。
- SSR中に外部APIを呼ぶ場合はレスポンス時間がページ表示速度に直結するため、キャッシュや遅延読み込みの検討が重要です。
まとめ
Nuxtの$fetchは、軽量で使いやすいHTTPリクエストヘルパーとして非常に便利ですが、SSRとCSRの特性を理解し適切に使うことが重要です。特にデータの二重取得や認証情報の扱いには注意が必要です。
- SSR中は
useFetchやuseAsyncDataと組み合わせて使う - 認証が必要なAPI呼び出しは
useRequestFetchでヘッダーを転送する - クライアントサイドの非同期通信には直接
$fetchを活用する
これらを踏まえて活用すれば、Nuxtアプリのデータ取得を効率化し、パフォーマンスとセキュリティを両立できます。
$fetchはNuxt 2の@nuxt/httpや@nuxtjs/axiosの推奨代替として設計されており、最新のNuxt 3環境でのHTTP通信に最適化されています。
※このページは Nuxt.js 公式ドキュメントの翻訳ページです。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/api/utils/dollarfetch