"use client" import { QueryClientProvider, type QueryClient } from "@tanstack/react-query" import { httpBatchLink } from "@trpc/client" import { createTRPCReact } from "@trpc/react-query" import { ReactNode, useState } from "react" import SuperJSON from "superjson" import type { AppRouterType } from "@backend/api/trpc/root" import { useToast } from "@frontend/hooks/use-toast" import createQueryClient from "@frontend/trpc/query-client" import { type LocaleType } from "@shared/i18n/t" import { useRouter } from "next/navigation" import useLocale from "@frontend/hooks/use-locale" import { RequestHeaderEnum } from "@shared/enums/request-header-enum" import { v4 as uuidv4 } from "uuid" import { clientEnv } from "@frontend/env/client-env" let cachedQueryClient: QueryClient | null = null function getQueryClient( locale: LocaleType, toast: ReturnType, router: ReturnType, ) { if (typeof window === "undefined") { return createQueryClient(locale, toast, router) } // Use cached query client to keep the same query client when in browser return (cachedQueryClient ??= createQueryClient(locale, toast, router)) } // Used for client-to-server communication export const trpcClientReact = createTRPCReact() export function TRPCReactProvider(props: { children: ReactNode }) { const locale = useLocale() const toast = useToast({ locale }) const router = useRouter() const queryClient = getQueryClient(locale, toast, router) const [trpcClient] = useState(() => trpcClientReact.createClient({ links: [ // There is an issue when setting server-side cookies with unstable_httpBatchStreamLink // https://github.com/trpc/trpc/discussions/4800 httpBatchLink({ transformer: SuperJSON, url: `${clientEnv.NEXT_PUBLIC_BACKEND_URL}/trpc`, headers: () => { const headers = new Headers() headers.set(RequestHeaderEnum.ACCEPT_LANGUAGE, locale) headers.set(RequestHeaderEnum.REQUEST_ID, uuidv4()) return headers }, fetch: async (url, options): Promise => { return await fetch(url, { ...options, credentials: "include", }) }, }), ], }), ) return ( {props.children} ) }