import getUrls from '@/config/urls'; import type { AppRouter } from '@/server/routers/_app'; import { createTRPCProxyClient, httpBatchLink, loggerLink } from '@trpc/client'; import { createTRPCNext } from '@trpc/next'; import type { NextPageContext } from 'next'; import SuperJSON from 'superjson'; import { isServer } from 'tools/common'; export type SSRContext = NextPageContext & { /** * Set HTTP Status code * * @example * const utils = trpc.useContext(); * if (utils.ssrContext) { * utils.ssrContext.status = 404; * } */ status?: number; }; const { BASE_PATH, PORT } = getUrls(); function getBaseUrl() { if (!isServer()) return BASE_PATH; return `http://localhost:${PORT ?? 3000}${BASE_PATH}`; } export const trpcClient = createTRPCNext({ config({ ctx }) { /** * If you want to use SSR, you need to use the server's full URL * * @link https://trpc.io/docs/ssr */ return { /** * @link https://trpc.io/docs/links */ links: [ // adds pretty logs to your console in development and logs errors in production loggerLink({ enabled: (opts) => process.env.NODE_ENV === 'development' || (opts.direction === 'down' && opts.result instanceof Error), }), httpBatchLink({ /** * Set custom request headers on every request from tRPC * * @link https://trpc.io/docs/ssr */ headers() { if (!ctx?.req?.headers) { return {}; } // To use SSR properly, you need to forward the client's headers to the server // This is so you can pass through things like cookies when we're server-side rendering const { // If you're using Node 18 before 18.15.0, omit the "connection" header connection: _connection, ...headers } = ctx.req.headers; return headers; }, url: `${getBaseUrl()}/api/trpc`, }), ], /** * @link https://trpc.io/docs/data-transformers */ transformer: SuperJSON, /** * @link https://react-query.tanstack.com/reference/QueryClient */ // queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } }, }; }, /** * Set headers or status code when doing SSR */ responseMeta(opts) { const ctx = opts.ctx as SSRContext; if (ctx.status) { // If HTTP status set, propagate that return { status: ctx.status, }; } const error = opts.clientErrors[0]; if (error) { // Propagate http first error from API calls return { status: error.data?.httpStatus ?? 500, }; } // for app caching with SSR see https://trpc.io/docs/caching return {}; }, /** * @link https://trpc.io/docs/ssr */ ssr: true, }); export type TRPCClient = typeof trpcClient; export const trpcPureClient = createTRPCProxyClient({ links: [ // adds pretty logs to your console in development and logs errors in production loggerLink({ enabled: (opts) => process.env.NODE_ENV === 'development' || (opts.direction === 'down' && opts.result instanceof Error), }), httpBatchLink({ url: `${getBaseUrl()}/api/trpc`, }), ], transformer: SuperJSON, }); export type TRPCPureClient = typeof trpcPureClient;