TanStack Query

TanStack Query でステータスページをフェッチ — useQuery ガイド

PulseAPI のステータスエンドポイントを useQuery で取得。キャッシュ、フォーカス時再取得、インターバルポーリング、SSE リアルタイム — 型付き React フックで完結。

TanStack Query のステータスページを公開する 3 つの方法

必要な制御レベルを選択 — ノーコード、ローコード、フルヘッドレス。

ホステッド

TanStack Query エンドポイントを追加し status.yourdomain.com に CNAME を向けるだけ。5 分で完成。

ヘッドレス

Public API を使って TanStack Query アプリ内に独自 UI を構築。デザインとブランディングを完全制御。

API を見る

埋め込みバッジ

SVG の稼働率・ステータスバッジを README やランディングに埋め込み。5 分ごとに自動更新。

この health エンドポイントを TanStack Query アプリに貼り付けます

コピペして PulseAPI を URL に向けるだけ。健康なら 200、劣化なら 503 を返します。

app/status/use-status-query.ts
import { useQuery } from '@tanstack/react-query'

interface StatusData {
  page: { title: string; customDomain: string | null }
  overallStatus: 'operational' | 'degraded' | 'down' | 'maintenance' | 'unknown'
  endpoints: Array<{
    id: string
    name: string
    status: string
    uptime24h: number
    avgResponseTime: number
  }>
}

export const useStatusQuery = (slug: string) =>
  useQuery<StatusData>({
    queryKey: ['status', slug],
    queryFn: async () => {
      const r = await fetch(`https://api.pulseapi.tech/status/${slug}`)
      if (!r.ok) throw new Error(`Status ${r.status}`)
      return r.json()
    },
    staleTime: 30_000,
    refetchInterval: 30_000,
    refetchOnWindowFocus: true,
  })

SSE ハートビートに合わせて staleTime と refetchInterval を 30 秒に設定してください。ポーリングなしのリアルタイム更新には /sse/status/:slug ストリームと併用し、イベント到達時に queryClient.setQueryData でキャッシュを更新します。

TanStack Query アプリで壊れるもの — それを検知する方法

長時間開いたタブで古いステータス

一晩開いたダッシュボードが本番停止中でも緑バナーを表示することがあります。refetchInterval と refetchOnWindowFocus でキャッシュを正しく保ちます。

再検証中に誤った表示がちらつく

placeholderData と keepPreviousData で再取得中も直前の正常ステータスを表示し続け、"operational" とスケルトンの間のちらつきを防ぎます。

入れ子コンポーネントからの並列リクエスト過多

複数コンポーネントが useStatusQuery を呼ぶと本来は各々がリクエストを発射しますが、React Query は queryKey で重複排除し slug ごとに同時 1 件に抑えます。

ヘッドレス視点

当社のステータスページが気に入らない? TanStack Query で自作してください。

当社 API はホステッド UI と同じデータを返します。完全な OpenAPI 仕様書は api.pulseapi.tech/docs.

components/StatusBanner.tsx — PulseAPI が劣化またはダウンを報告した際にアプリ内へインラインバナーを表示。
import { useStatusQuery } from './use-status-query'

export function StatusBanner({ slug }: { slug: string }) {
  const { data, isLoading, error } = useStatusQuery(slug)

  if (isLoading) return <div className="skeleton" />
  if (error) return null
  if (!data) return null
  if (data.overallStatus === 'operational') return null

  return (
    <a href={`https://${data.page.customDomain}`} className="banner">
      {data.overallStatus === 'down' ? 'Service disruption' : 'Degraded service'}
      {' — '}
      {data.endpoints.filter((e) => e.status !== 'operational').length} affected
    </a>
  )
}

TanStack Query 監視 — FAQ

リアルタイム更新のために useQuery と SSE をどう組み合わせますか?

useEffect 内で /sse/status/:slug に EventSource を開き、各イベントで queryClient.setQueryData(["status", slug], to merge event patches into the existing cache entry を呼びます。useQuery 購読側はポーリングなしで最新状態になります。

TanStack Query v4 と v5 で動きますか?

どちらも。v4 は cacheTime、v5 では gcTime に改名。v5 の isLoading は厳密に「初回ロード」のみを指します。任意の in-flight 表示には isPending + isFetching を使ってください。

Next.js や Remix でサーバー側でステータスをプリフェッチできますか?

はい。server component またはローダーで queryClient.prefetchQuery を呼び、ツリーを v5 の HydrationBoundary または v4 の Hydrate で dehydrated state とともにラップ。useStatusQuery フックは初回描画でハイドレート済みキャッシュから読み込むためクライアントでちらつきません。

組織 API キーを useQuery で使うのは安全ですか?

いいえ — ブラウザ JS に置いたキーは公開されたも同然です。公開ステータスエンドポイントは認証不要。組織 API キーはサーバー側のみ。認証が必要なら /api/status などのバックエンドルート経由でプロキシし、useQuery からそれを呼んでください。

TanStack Query アプリの監視を 5 分で開始

無料プラン、クレジットカード不要。エンドポイントを追加して障害時にアラート。