1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nuxtにおけるキャッシュ戦略まとめ(SSR / SSG / Nitro対応)

1
Last updated at Posted at 2026-03-18

1. はじめに

Nuxtで開発していると、

  • 更新したのに画面が変わらない
  • APIの結果が古いまま
  • 本番だけ挙動が違う

といったキャッシュ絡みの問題に遭遇することがあります。

本記事では、Nuxt(主にNuxt3)におけるキャッシュの仕組みと実務での対処法を整理します。


2. Nuxtのキャッシュはどこに存在するか

Nuxtのキャッシュは複数のレイヤーに分かれています。

キャッシュの種類

レイヤー 内容
ブラウザ HTTPキャッシュ / Service Worker
CDN Cloudflare / Vercel など
サーバー(Nitro) APIレスポンスキャッシュ
アプリ内部 useAsyncData / useFetch

重要なのは「どのレイヤーでキャッシュされているか」を切り分けることです。


3. useAsyncData / useFetch のキャッシュ

Nuxt3ではデータ取得に useAsyncData や useFetch を使用します。

基本例

const { data } = await useAsyncData('posts', () => $fetch('/api/posts'))
  • クライアント遷移時は再取得されない
  • 同じキー('posts')はキャッシュされる

キャッシュを無効にする

const { data } = await useFetch('/api/posts', {
  cache: 'no-cache'
})

手動で再取得

const { refresh } = await useAsyncData(...)
refresh()

動的キーでキャッシュ制御

const route = useRoute()

const { data } = await useAsyncData(
  () => `posts-${route.params.id}`,
  () => $fetch(`/api/posts/${route.params.id}`)
)

4. サーバーキャッシュ

キャッシュ設定

export default defineNuxtConfig({
  routeRules: {
    '/api/posts': { cache: { maxAge: 60 } }
  }
})

→ 60秒キャッシュされる

キャッシュ無効化

'/api/posts': { cache: false }

ISR(Incremental Static Regeneration)

'/blog/**': { isr: 60 }

→ 60秒ごとに再生成

5. HTTPキャッシュ(ブラウザ / CDN)

APIレスポンスにヘッダーを設定することで制御できます。

設定例

export default defineEventHandler((event) => {
  setHeader(event, 'Cache-Control', 's-maxage=60, stale-while-revalidate')
  return { message: 'hello' }
})

よく使う設定

  • no-cache:毎回サーバー確認
  • no-store:キャッシュしない
  • max-age:ブラウザキャッシュ
  • s-maxage:CDNキャッシュ
  • stale-while-revalidate:古いデータを返しつつ裏で更新

6. よくあるハマりポイント

APIは更新しているのに画面が変わらない

原因

  • useAsyncDataのキャッシュ
  • Nitroキャッシュ
  • CDNキャッシュ

対策

  • キーを変更する
  • refresh()を使う
  • cache: false にする

本番だけ更新されない

原因

  • CDNキャッシュ(Cloudflare / Vercel)

対策

  • Cache-Controlを確認
  • キャッシュパージ

ページ遷移でデータが変わらない

原因

  • useAsyncDataのキーが固定

対策

const route = useRoute()

const { data } = await useAsyncData(
  () => `posts-${route.params.id}`,
  () => $fetch(`/api/posts/${route.params.id}`)
)

8. まとめ

Nuxtのキャッシュは以下の4層で考えると理解しやすいです。

  • ブラウザ
  • CDN
  • サーバー(Nitro)
  • アプリ内部(useAsyncData)
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?