"use client";
import { QueryClientProvider, type QueryClient } from "@tanstack/react-query";
import { loggerLink, unstable_httpBatchStreamLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
import { useState } from "react";
import SuperJSON from "superjson";
import { type AppRouter } from "@/schema/trpc-types"; // generated types
import { createQueryClient } from "./query-client";
let clientQueryClientSingleton: QueryClient | undefined = undefined;
const getQueryClient = () => {
if (typeof window === "undefined") {
return createQueryClient();
}
return (clientQueryClientSingleton ??= createQueryClient());
};
export const api = createTRPCReact<AppRouter>();
export type RouterInputs = inferRouterInputs<AppRouter>;
export type RouterOutputs = inferRouterOutputs<AppRouter>;
export function TRPCReactProvider(props: { children: React.ReactNode }) {
const queryClient = getQueryClient();
const [trpcClient] = useState(() =>
api.createClient({
links: [
loggerLink({
enabled: (op) =>
process.env.NODE_ENV === "development" ||
(op.direction === "down" && op.result instanceof Error),
}),
unstable_httpBatchStreamLink({
transformer: SuperJSON,
url: "http://localhost:3000/api/trpc", // main project api endpoint
headers: () => {
const headers = new Headers();
headers.set("x-trpc-source", "nextjs-react");
headers.set("Content-Type", "application/json");
return headers;
},
fetch(url, options) {
return fetch(url, {
...options,
credentials: "include",
});
},
}),
],
}),
);
return (
<QueryClientProvider client={queryClient}>
<api.Provider client={trpcClient} queryClient={queryClient}>
{props.children}
</api.Provider>
</QueryClientProvider>
);
}