Openstatus
www.openstatus.dev
1"use client";
2
3import type { AppRouter } from "@openstatus/api";
4import type { QueryClient } from "@tanstack/react-query";
5import { QueryClientProvider } from "@tanstack/react-query";
6import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
7import { createTRPCReact } from "@trpc/react-query";
8import { useState } from "react";
9import { makeQueryClient } from "./query-client";
10import { endingLink } from "./shared";
11
12export const api = createTRPCReact<AppRouter>();
13let clientQueryClientSingleton: QueryClient;
14function getQueryClient() {
15 if (typeof window === "undefined") {
16 // Server: always make a new query client
17 return makeQueryClient();
18 }
19 // Browser: use singleton pattern to keep the same query client
20 // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
21 return (clientQueryClientSingleton ??= makeQueryClient());
22}
23
24export function TRPCReactQueryProvider(
25 props: Readonly<{
26 children: React.ReactNode;
27 }>,
28) {
29 // NOTE: Avoid useState when initializing the query client if you don't
30 // have a suspense boundary between this and the code that may
31 // suspend because React will throw away the client on the initial
32 // render if it suspends and there is no boundary
33 const queryClient = getQueryClient();
34 const [trpcClient] = useState(() =>
35 api.createClient({
36 links: [
37 endingLink({
38 headers: {
39 "x-trpc-source": "client",
40 },
41 }),
42 ],
43 }),
44 );
45 return (
46 <api.Provider client={trpcClient} queryClient={queryClient}>
47 <QueryClientProvider client={queryClient}>
48 {props.children}
49 <ReactQueryDevtools initialIsOpen={false} />
50 </QueryClientProvider>
51 </api.Provider>
52 );
53}