Live playground
All widgets import tanstack-fetch from source and use a mock fetch / stream. Not screenshots.
Open in StackBlitz
| Example | StackBlitz | Docs |
|---|---|---|
| TanStack Query | Open | React |
| Next.js SSR | Open | SSR |
| Upload | Open | Upload |
| SSE | Open | SSE |
| tRPC | Open | tRPC recipe |
| Auth status | Open | Refresh |
Status matrix (incl. 429)
Live demo · real createFetch
Trigger HTTP statuses
Mock fetch returns the code you click. Handlers fire before FetchError is thrown — including 429 with Retry-After.
Tap a status — real createFetch + mock fetch
Event log
Handlers and throws show up here.
const api = createFetch({
onTooManyRequests: ({ context }) => {
const waitMs = parseRetryAfter(context.response?.headers)
// show toast / backoff…
},
onClientError: ({ status }) => console.warn('4xx', status),
onUnauthorized: () => logout(),
})React / TanStack Query
Live demo · React / TanStack Query
useQuery + useMutation shape
Real createFetch calls — same queryFn / mutationFn contract your React app uses.
idle — click useQuery
const api = createFetch({ baseUrl })
// React Query
useQuery({
queryKey: ['users'],
queryFn: ({ signal }) => api.get<User[]>('/users', { signal }),
})
useMutation({
mutationFn: (body) => api.post<User>('/users', { body }),
})Next.js SSR
Live demo · Next.js SSR
ssr-forward cookie / auth
Real createFetch with source: 'ssr' + ssr-forward — watch headers get attached (then skipped in browser).
Request log
Run server prefetch to see forwarded Cookie / Authorization.
// app/users/page.tsx (Next.js App Router)
import { cookies } from 'next/headers'
import { createFetch } from 'tanstack-fetch'
const createServerApi = async () =>
createFetch({
baseUrl: process.env.API_URL!,
source: 'ssr',
plugins: ['ssr-forward', 'trace'],
incoming: async () => ({
cookie: (await cookies()).toString(),
}),
})
await queryClient.prefetchQuery({
queryKey: ['users'],
queryFn: async () => (await createServerApi()).get('/users'),
})Upload
Live demo · Upload
api.upload + multipart fields
Real api.upload() builds FormData and posts through createFetch. Add onUploadProgress in your app for XHR progress.
No file selected
Pick a file and upload — real api.upload() + mock fetch
await api.upload('/files', {
file,
fieldName: 'file',
fields: { folder: 'avatars', public: true },
onUploadProgress: ({ progress }) => setProgress(progress),
})SSE
Live demo · SSE
api.sse over fetch
Real tanstack-fetch/sse against a mock event stream — cookies / Authorization work (unlike EventSource).
Idle — start the stream
import { createFetch } from 'tanstack-fetch/sse'
const api = createFetch({
plugins: ['sse-resume'],
getToken: () => localStorage.getItem('access_token'),
})
const stream = api.sse<Tick>('/orders/stream', {
onMessage: (data) => setTicks((t) => [data, ...t]),
})
// stream.close()queryFn shape
Live demo · queryFn shape
Returns data · throws on error
Click Run — this calls createFetch against a mock API
const api = createFetch({ baseUrl, fetch: mockFetch })
// same shape as TanStack Query queryFn
const users = await api.get<User[]>('/users')
