"use client" import { QueryCache, QueryClient, QueryClientProvider, } from "@tanstack/react-query" import { httpBatchLink, loggerLink, TRPCClientError } from "@trpc/client" import { AnyTRPCRouter } from "@trpc/server" import { useState } from "react" import { login } from "@/constants/routes/handleAuth" import { env } from "@/env/client" import { SessionExpiredError } from "@/server/errors/trpc" import { transformer } from "@/server/transformer" import { trpc } from "./client" import { LangParams } from "@/types/params" function initializeTrpcClient() { // Locally we set nextjs to run on port to 3000 so that we always guarantee // that trpc and next are running on the same port. return trpc.createClient({ links: [ loggerLink({ enabled: (opts) => (env.NEXT_PUBLIC_NODE_ENV === "development" && typeof window !== "undefined") || (opts.direction === "down" && opts.result instanceof Error), }), httpBatchLink({ fetch, transformer, /** * This is locally in Next.js */ url: `http://localhost:${env.NEXT_PUBLIC_PORT}/api/web/trpc`, }), ], }) } export default function TrpcProvider({ children, lang, }: React.PropsWithChildren) { const [queryClient] = useState( () => new QueryClient({ queryCache: new QueryCache({ async onError(error) { if (error instanceof TRPCClientError) { const appError: TRPCClientError = error console.log({ appError }) if (appError.data?.code === "UNAUTHORIZED") { if (appError.data?.cause instanceof SessionExpiredError) { const loginUrl = login[lang] window.location.assign(loginUrl) } } } }, }), defaultOptions: { queries: { staleTime: 3000, retry(failureCount, error) { if (error instanceof TRPCClientError) { const appError: TRPCClientError = error // Do not retry query requests that got UNAUTHORIZED error. // It won't make a difference sending the same request again. if (appError.data?.code) { if ( [ "UNAUTHORIZED", "INTERNAL_SERVER_ERROR", "FORBIDDEN", ].includes(appError.data.code) ) { return false } } } // Retry all client requests that fail (and are not handled above) // at most 3 times. return failureCount < 3 }, }, }, }) ) const [trpcClient] = useState(() => initializeTrpcClient()) return ( {children} ) }