\r\n \u003C/Hydrate>\r\n\u003C/QueryProvider>\r\n```\r\n\r\nAnd then `createTRPCReact` can just return a comprehensive object of helper queries and exposure of helpful internal functions like so:\r\n\r\n```tsx\r\ntype AppRouter = { myProcedure: {...} }\r\n\r\nconst trpc = createTRRCReact\u003CAppRouter>(trpcRelatedConfigHere)\r\n\r\n// Using a procedure's helpers\r\ntrpc.myProcedure.useQuery(...)\r\ntrpc.myProcedure.useInfiniteQuery(...)\r\ntrpc.myProcedure.key(...) // \u003C- useful for react-query idiomatic SSG\r\ntrpc.myProcedure.fetcher(...) // \u003C- ^^\r\n\r\n// Using TRPC helpers\r\n```tsx\r\ntrpc.dehydrate() // \u003C- Light wrapper over react query dehydrate, including appropriate serialisation/any necessary mods\r\n```\n\n### Describe alternate solutions\n\nCurrently it's not clear that I can actually perform half the React Query things that I used to with `tRPC`s wrappers.\r\n\r\nIn the case of SSG, perhaps it's possible to create a vanilla client and react client, use `getQueryKey` and the vanilla client to re-enter the idiomatic react query approach a la\r\n\r\n```tsx\r\nqueryClient.prefetch(\r\n getQueryKey(...), // \u003C- Key\r\n () =>. trpc.my.procedure.query(...) // \u003C- fetcher\r\n)\r\nreturn { props: { trpcState: SuperJSON.serialize(dehydrate(queryClient)) } }\r\n```\r\n\r\nHowever I haven't been able to get this working just yet.\n\n### Additional information\n\nI appreciate this suggestion is somewhat radical, and don't mean to come across as denigrating the work done here. I just think for the sanity of both the `tRPC` maintainers and users, integrating with already complicated tools like React Query should be done with minimal modification, lest you're on the hook for much more documentation, maintenance and functionality parity.\r\n\r\nWith all of this said, I'm more than happy to have a go at rethinking this. Of course, since it's a bold change, I wouldn't expect immediate acceptance. In any case, I'll be prototyping a solution like the above in my own application in the meantime, as SSG is a blocker for my migration to `tRPC`, so I can share or PR this solution when appropriate 👍.\r\n\r\nOutside of this hurdle, I have been really enjoying using `tRPC`. In fact it inspired part of the API for another recent [project of mine](https://github.com/sinclairnick/brail).\n\n### 👨👧👦 Contributing\n\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!\n\n\u003Csub>[TRP-18](https://linear.app/trpc/issue/TRP-18/feat-make-react-query-integration-less-opaque)\u003C/sub>",[2933],{"name":2934,"color":2935},"@trpc/react-query","375E6E",4012,"feat: Make React-Query integration less opaque","2025-03-20T15:41:35Z","https://github.com/trpc/trpc/issues/4012",0.69619834,{"description":2942,"labels":2943,"number":2945,"owner":2871,"repository":2871,"state":2890,"title":2946,"updated_at":2947,"url":2948,"score":2949},"I just started using `trpcNext.CreateNextContextOptions` and noticed that it’s typed as follows:\r\n\r\n```ts\r\ntype CreateNextContextOptions = {\r\n req: NextApiRequest,\r\n res: NextApiResponse,\r\n};\r\n```\r\n\r\nWhile it works great for API requests, the `context` that gets passed to `getServerSideProps` only contains a portion of this information – the basis of `NextApiRequest` and `NextApiResponse` objects:\r\n\r\n```ts\r\nimport type { IncomingMessage, ServerResponse } from \"http\";\r\n\r\ntype GetServerSidePropsContextOptions = {\r\n req: IncomingMessage & { cookies: NextApiRequestCookies },\r\n res: ServerResponse,\r\n};\r\n```\r\n\r\nIn order to support SSR better and keep the API context versatile, I propose a context in which only the `req` object is mandatory during SSR, as responses shouldn’t be altered in that case. API functionality is kept intact:\r\n\r\n```ts\r\ntype CreateNextContextOptions =\r\n | {\r\n req: NextApiRequest;\r\n res: NextApiResponse;\r\n }\r\n | {\r\n req: IncomingMessage & { cookies: NextApiRequestCookies };\r\n // Altering responses during SSR isn’t a good idea:\r\n res?: never; // Previous thought: `res?: ServerResponse;`\r\n };\r\n```",[2944],{"name":2915,"color":2916},366,"Loosen `trpcNext.CreateNextContextOptions` type for better SSR support","2021-05-16T15:19:21Z","https://github.com/trpc/trpc/issues/366",0.69839436,{"description":2951,"labels":2952,"number":2956,"owner":2871,"repository":2871,"state":2890,"title":2957,"updated_at":2958,"url":2959,"score":2960},"### Describe the feature you'd like to request\r\n\r\nClose your eyes. **Imagine a world** where you can combine the typesafety of tRPC and the expressiveness of JSX for a heavenly API building experience. Now open your eyes. You don't have to imagine it. It's right in front of you.\r\n```tsx\r\nconst SessionContext = createContext();\r\nconst UserContext = createContext();\r\n\r\nconst ProtectedProcedure = (props: { children: ReactNode }) => {\r\n const session = useContext(UserContext);\r\n\r\n if (!session || !session.user) {\r\n throw new TRPCError({ code: \"UNAUTHORIZED\" });\r\n }\r\n\r\n return (\r\n \u003CUserContext.Provider value={session.user}>\r\n {props.children}\r\n \u003C/UserContext.Provider>\r\n );\r\n};\r\n\r\nconst GreetingProcedure = () => {\r\n const { name } = useArgsContext();\r\n return `Hello ${name}`;\r\n};\r\n\r\nconst GetUserProcedure = () => {\r\n const user = useContext(UserContext);\r\n\r\n return user;\r\n};\r\n\r\nconst AppRouter = withTRPC(() => {\r\n const { req, res } = useTrpcRequestContext();\r\n const session = useMemo(() => getServerAuthSession(req, res), []);\r\n\r\n return (\r\n \u003CSessionContext.Provider value={session}>\r\n \u003Crouter>\r\n \u003Cquery name=\"greeting\">\r\n \u003CZodParser schema={z.object({ name: z.string() })}>\r\n \u003CGreetingProcedure />\r\n \u003C/ZodParser>\r\n \u003C/query>\r\n \u003Cquery name=\"getUser\">\r\n \u003CProtectedProcedure>\r\n \u003CGetUserProcedure />\r\n \u003C/ProtectedProcedure>\r\n \u003C/query>\r\n \u003C/router>\r\n \u003C/SessionContext.Provider>\r\n );\r\n});\r\n```\r\n\r\nLet's break this down.\r\n\r\n# Rendering\r\nEach request corresponds to a render. Only those procedures requested will be run on each render.\r\n```ts\r\nconst AppRouter = withTRPC(() => {\r\n // ...\r\n});\r\n```\r\nThe `withTRPC` function wrapper is necessary to get `req` and `res`.\r\n\r\n# Context\r\nAll context will be done like React:\r\n```tsx\r\nconst SessionContext = createContext();\r\n\r\nconst AppRouter = withTRPC(() => {\r\n const { req, res } = useTrpcRequestContext();\r\n const session = useMemo(() => getServerAuthSession(req, res), []);\r\n\r\n return (\r\n // session will be passed down to all procedures\r\n \u003CSessionContext.Provider value={session}>\r\n {/* ... */}\r\n \u003C/SessionContext.Provider>\r\n );\r\n});\r\n```\r\n\r\n# Middleware\r\nReact already has a composition pattern so we can just hook into that for middleware:\r\n```ts\r\nconst ProtectedProcedure = (props: { children: ReactNode }) => {\r\n // session passed down from `SessionContext.Provider`\r\n const session = useContext(UserContext);\r\n\r\n // bail out if no user\r\n if (!session || !session.user) {\r\n throw new TRPCError({ code: \"UNAUTHORIZED\" });\r\n }\r\n\r\n return (\r\n \u003CUserContext.Provider value={session.user}>\r\n {props.children}\r\n \u003C/UserContext.Provider>\r\n );\r\n};\r\n```\r\n\r\n# Procedures\r\nThere are a few internal JSX elements for declaring procedures: `query`, `mutation`, and `subscription`, all which require the procedure name.\r\n```ts\r\n// this is the actual resolver for the procedure\r\nconst GreetingProcedure = () => {\r\n // automatically typed (call it a gift from God)\r\n const { name } = useArgsContext\u003C{ name: string }>();\r\n\r\n return `Hello ${name}`;\r\n};\r\n\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n {/* this marks the procedure as a query in the router tree */}\r\n \u003Cquery name=\"greeting\">\r\n \u003CGreetingProcedure />\r\n \u003C/query>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n## Input Validation\r\n```ts\r\nconst GreetingProcedure = () => {\r\n const { name } = useArgsContext();\r\n\r\n return `Hello ${name}`;\r\n};\r\n\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n \u003Cquery name=\"greeting\">\r\n {/* this parses the input data from the request and passes it on using the internal ArgsContext */}\r\n \u003CZodParser schema={z.object({ name: z.string() })}>\r\n \u003CGreetingProcedure />\r\n \u003C/ZodParser>\r\n \u003C/query>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n\r\n# Router\r\nRouters and procedures can be nested like any other JSX element:\r\n```ts\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n \u003Cquery name=\"greeting\">\r\n \u003CGreetingProcedure />\r\n \u003C/query>\r\n {/* everything under this router will be mounted at user.* */}\r\n \u003Crouter name=\"user\">\r\n {/* this mutation is mounted at user.createUser */}\r\n \u003Cmutation name=\"createUser\">\r\n \u003CZodParser schema={z.object({ name: z.string(), age: z.number() })}>\r\n \u003CCreateUserMutation />\r\n \u003C/ZodParser>\r\n \u003C/mutation>\r\n \u003C/router>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n### Describe alternate solutions\r\n\r\nMaybe Svelte or Vue could offer better syntax and typesafety 🧐\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!",[2953],{"name":2954,"color":2955},"RFC","78B062",4124,"[RFC]: tRPC Server JSX API","2023-04-21T18:01:53Z","https://github.com/trpc/trpc/issues/4124",0.69849753,{"description":2962,"labels":2963,"number":2965,"owner":2871,"repository":2871,"state":2890,"title":2966,"updated_at":2967,"url":2968,"score":2969},"> Also, as you're pointing out, RSC will hopefully fix this for us. I don't want to put too much more effort into `withTRPC` in it's current form as it will _hopefully_ be deprecated pretty soon (that said, for v10, we should probably make sure we have an API design that makes it tree shakable when/if that happens 😅 )\r\n>\r\n> _Originally posted by @KATT in https://github.com/trpc/trpc/issues/2625#issuecomment-1240397342_\r\n\r\n\r\nMaybe we should move the `withTRPC` to it's own `import` so it can be tree-shaken when/if [RSC](https://nextjs.org/docs/advanced-features/react-18/server-components) or the [Next.js Layouts](https://nextjs.org/blog/layouts-rfc) arrives so it can be tree-shaken as it will will likely have to be non-compatible to that API or make a bunch of stuff redundant.\r\n\r\n\r\n## Suggested change\r\n\r\n\r\n#### Before\r\n\r\n```tsx\r\n\r\n// _app.tsx\r\nimport { AppType } from 'next/dist/shared/lib/utils';\r\nimport { ReactElement, ReactNode } from 'react';\r\nimport { trpc } from '~/utils/trpc';\r\n\r\nconst MyApp: AppType = (({ Component, pageProps }) => {\r\n return \u003CComponent {...pageProps} />;\r\n})\r\n\r\nexport default trpc.withTRPC(MyApp);\r\n```\r\n\r\n#### After\r\n\r\n> Not thrilled about exactly this API-design, but gets the point across that `withTRPC()` can be tree shaken, feel free to do other suggestions\r\n\r\n```ts\r\n// _app.tsx\r\nimport { AppType } from 'next/dist/shared/lib/utils';\r\nimport { trpc } from '~/utils/trpc';\r\nimport { createTRPCNextWithTRPC } from '@trpc/next';\r\n\r\nconst MyApp: AppType = (({ Component, pageProps }) => {\r\n return \u003CComponent {...pageProps} />;\r\n})\r\n\r\nexport default createWithTRPC(trpc)(MyApp);\r\n```\r\n",[2964],{"name":2954,"color":2955},2650,"Break out `withTRPC` from `createTRPCNext`?","2022-11-04T00:06:57Z","https://github.com/trpc/trpc/issues/2650",0.70080405,["Reactive",2971],{},["Set"],["ShallowReactive",2974],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fSQlgT-5Hog_r5HZvT1GHJVq2anugcB80OgOjDHIPtPo":-1},"/trpc/trpc/6467"]