QUESTPIE
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-query

Collection 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>
  );
}

On this page