Integrate Frontend
TanStack Query
React hooks for data fetching with TanStack Query integration.
QUESTPIE integrates with TanStack Query for React-based data fetching with caching, refetching, and optimistic updates.
Setup
bun add @questpie/tanstack-query @tanstack/react-queryCollection Hooks
import { useCollectionList, useCollectionItem } from "@questpie/tanstack-query";
import type { AppConfig } from "#questpie";
// List with filters
function ServiceList() {
const { data, isLoading } = useCollectionList<AppConfig>("services", {
where: { isActive: true },
orderBy: { name: "asc" },
limit: 20,
});
if (isLoading) return <div>Loading...</div>;
return (
<ul>
{data?.docs.map((service) => (
<li key={service.id}>
{service.name} — {service.price}¢
</li>
))}
</ul>
);
}
// Single item
function ServiceDetail({ id }: { id: string }) {
const { data: service } = useCollectionItem<AppConfig>("services", {
where: { id },
with: { barbers: true },
});
if (!service) return null;
return <div>{service.name}</div>;
}Mutation Hooks
import {
useCollectionCreate,
useCollectionUpdate,
} from "@questpie/tanstack-query";
function CreateServiceForm() {
const create = useCollectionCreate<AppConfig>("services");
const handleSubmit = (data) => {
create.mutate({
name: data.name,
duration: data.duration,
price: data.price,
isActive: true,
});
};
return <form onSubmit={handleSubmit}>...</form>;
}Global Hooks
import { useGlobal, useGlobalUpdate } from "@questpie/tanstack-query";
function SiteSettings() {
const { data: settings } = useGlobal<AppConfig>("siteSettings");
const update = useGlobalUpdate<AppConfig>("siteSettings");
return (
<div>
<h1>{settings?.shopName}</h1>
<button onClick={() => update.mutate({ shopName: "New Name" })}>
Update
</button>
</div>
);
}Direct Client Usage
You can also use the client directly with TanStack Query:
import { useQuery, useMutation } from "@tanstack/react-query";
import { client } from "@/lib/client";
function BookingForm() {
const { data: barbers } = useQuery({
queryKey: ["barbers", "active"],
queryFn: () => client.routes.getActiveBarbers({}),
});
const booking = useMutation({
mutationFn: (data) => client.routes.createBooking(data),
});
return (
<form onSubmit={(e) => {
e.preventDefault();
booking.mutate({ barberId: "...", serviceId: "...", ... });
}}>
{/* form fields */}
</form>
);
}Related Pages
- Querying — Query operators and pagination
- Realtime — Live subscriptions
- Type Inference — End-to-end types