Use API in frontend
Typed Hono client, handle(), TanStack Query, and storefront checkout exceptions.
Marketing talks to the product API through a typed Hono client plus TanStack Query. There is no serverApi() helper and no oRPC client.
Client setup
import { createApiClient, handle } from "@repo/api/client";
import { clientEnv } from "@repo/env/client";
export const api = createApiClient(
`${clientEnv.NEXT_PUBLIC_MARKETING_URL}/api`,
);
export { handle };createApiClient wraps hc<AppRouter> with credentials: "include" so session cookies are sent on same-site / CORS-credentialed requests.
handle() awaits the response, parses JSON, and throws Error with the API message when !res.ok.
Client component + TanStack Query
Wrap typed calls in mutations (or queries) under apps/marketing/src/mutations/:
"use client";
import { useMutation } from "@tanstack/react-query";
import { api, handle } from "@/lib/api";
import type { CreateFeedbackData } from "@repo/validations/feedback";
export const useCreateFeedback = () => {
return useMutation({
mutationFn: (data: CreateFeedbackData) =>
handle<{
success: true;
feedback: { id: string; type: string; createdAt: string };
}>(api.feedback.$post({ json: data })),
});
};Call sites use the hook from client components. Keep product mutations on this path — do not use the Better Auth client for them, and do not add "use server" actions for product features.
Server Components / RSC
There is no serverApi(). For RSC, prefer not calling the product API unless you need it; today marketing product mutations are client-side. If you must call from the server, use a same-origin fetch to /api/… (or call a service function directly from a trusted server context) — do not invent a parallel typed helper.
Storefront checkout exception
Mayar storefront checkout uses a dedicated Next route, not the Hono billing module:
await fetch("/api/checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ plan }),
});See apps/marketing/src/app/api/checkout/route.ts and use-create-checkout.ts.