The goal of this chapter is to integrate DRPC inside of our project. So why did I even choose DRPC for this project? Well, first of all, end-to-end type safety. You've probably noticed that this is something that I'm quite fond of, especially in some of my previous tutorials where I chose to integrate HONO inside of our Next.js project. And then I leveraged HONO's RPC procedures so that I can have very nice and type-safe API routes, results, mutations, queries, all of those things.
Well, tRPC is, I would say, a step ahead of that. Precisely comparing to HONO RPC. I'm not comparing TRPC with HONO, right? Those are two different things. I'm comparing HONO RPC with TRPC.
In this case, TRPC is a bit superior. I would definitely say so. Specifically because we have a much, much closer integration to React Query, which allows us to use UseQuery and UseMutation and all of those other hooks you've heard of coming from UseQuery natively. What do I mean natively? I mean for every single procedure that we create inside of TRPC, we will automatically have useQuery, useMutation, and all the relevant queries and functions and hooks generated automatically.
In my HONA RPC integration, I had to write these myself. But with TRPC they will come generated out of the box. But none of that is the actual reason why I chose TRPC. The actual reason I chose tRPC is because version 11 of tRPC finally allows us to do authenticated prefetching. So no matter how much I liked HONO RPC, one thing that HONO RPC was not able to do was do an API call instead of a server component, which is basically this right here, right?
Imagine this said HONO instead of TRPC. That was not possible. The reason it was not possible is because what HONO did in the background is it would initialize a fetch API call in a server component. That's completely fine, nothing wrong with that, but that's not a native RPC call on the server. It is a server which is calling fetch to my very own server, right?
Not exactly elegant nor optimized, but the most important thing that happened is that the headers got lost, meaning that in Hono it was not possible to prefetch authenticated queries. We could only prefetch public database queries. We could never do prefetching for something that's specific to one user. So that was a big issue. And when I found out that version 11 of tRPC has solved this issue, I had to try it and trust me, it's worth it.
I think you're absolutely going to love it. It is understandable if you are a bit confused by this intro. This is all very new, especially if you've never heard about prefetching or server components in the first place. So I'm going to try my best to explain it and we're going to slowly build around this concept and get familiar with it. So I hope it will finally click for you as well as it did for me while I was building this.
So why do I care about pre-fetching that much? First of all, I very very much like the render as you fetch concept because this specifically means faster load times and they are definitely visible, right? When I tested a prefetched server components versus just a client component fetching for the first time, the prefetched server component was visibly much, much faster. Besides that, we also have parallel data loading, and one concept that I really like, which is leveraging React server components as loaders. So this is where I finally saw React server components as, okay, this is what I want to use them for every single time.
This is why they are so powerful for. And this is the pattern that we're going to try to achieve. Keep in mind that I made this graph and I have no idea if this graph is breaking all the rules of any other sorry not graph the diagram. I'm just trying to translate what's in my head inside of here so I hope you will understand. Basically we're going to start with the server component, which will use tRPC version 11 to prefetch data.
And it can also prefetch authenticated data, which is something which was not possible before. So I never really entertained this idea of server-first data pattern. But now that we can do authenticated calls, this is completely doable. So we're going to use a server component to prefetch the data. Thanks to TRPC's very close React query integration, it will automatically be set inside of React Query's data cache.
And then we're going to create a Hydrate Client Component in which we are going to wrap our Client Component so that our Client Component can easily access the cache which was prefetched right here. And then, in case we need to revalidate our client component, we are going to keep that inside of this layer right here between the data cache and the client component. So we are not going to go back to server components, we are not going to do any revalidate or revalidate path or any of those things. It's going to be like this. We're going to leverage this new thing, server components, to speed up our app and we are going to continue using our familiar client components just as we've learned to use them in years of previous React tutorials, right?
This is a pattern that I really like because we are leveraging server components to truly speed up our application, but we are also leveraging our existing knowledge of client components to continue doing everything we know and love about them. If this diagram doesn't make sense, I prepared a code snippet here. So inside of here we have an example videos dynamic video id page.dsx route and inside of here I have a server component and inside of here this is what we are going to do. We are going to call trpc.videos.prefetch. And we're going to prefetch a single video ID.
And then we're going to use this Hydrate client, which we're going to create inside of this TRPC setup, to wrap our VideoClient component. You can see that in this VideoClient component, the only thing I'm passing is the VideoID prop. I'm not waiting for any data to be loaded here. I'm just prefetching the data in the server component. Then once it's been preloaded from server and cache, what I will be able to do in the video client here is use the rpc.videos that use suspense query and simply pass that video ID.
And this right here is already populated. So you can see that instead of my videos, I can immediately do .map. I don't have to do, if this was waiting for load, it would have to do videos?.map. Right? Because it's possible for videos to be undefined.
Well, not possible in this case, because the moment this video client component is rendered, this has already been prefetched. So that's why this is a much faster concept for us to work with. And of course, we're also going to leverage suspense and error boundaries to display nice loading states. And then we're going to try and do both of this. We're going to try one trpc.videos.normalusequery, and we're going to do one with the prefetch here, and we're going to see which one appears faster.
And let me already tell you the answer. This one will be much, much faster. That being said, this is a fairly new pattern, right? I have contacted the creators of TRPC for their opinions. Is this something that I can teach?
Is this an invalid pattern? And I've gotten a confirmation from them that this is an okay pattern. This is, as far as they know, the best way to do this kind of pattern. So it's not something I have invented myself and now trying to force onto you. Great.
So let's go ahead and try and do this. So for this chapter, we're not really going to have any complex queries, but I do hope that we will at least be able to make this kind of example. One server component prefetching and then a client component using that pre-fetched data inside of it. Great! So we're going to start by going to the TRPC website.
So move fast and break nothing end-to-end type safe APIs made easy. So depending on when you are watching this, you might or might not see this version right here, which is you are looking at TRPC version 11, right? So if you click here to see the list of changes for version 11, you go ahead and click here. Here's the thing, version 11 is not currently out, meaning that if you go ahead and go write npm info, for example, let me see one package, so trpc slash server, for example, if I do this, let me just find, there we go, you can see that the latest version is 10.45.2, right? That is the latest version.
But inside of here, it clearly says that version 11 is the newest version. Well, it's not fully out. This is the state of it. This is a current work in progress representing version 11. But The current functionality of version 11 is stable and it can be used in production.
The reason they are adding this alert is because they might have some small breaking API changes between patches until they reach this version right here. So this is what we are going to do. We're going to go ahead and click on Docs here. Let's click on Quick Start and let's go ahead and find... Okay, we actually have Using Next.js here.
I would highly recommend that you go to the documentation as well so you can see exactly what I'm seeing here. So click on using Next.js right here and we can click on setup here and then we have this caution here. This guide is for Next.js pages router. If you're using Next.js app router with server components check out the React server component docs. So you can just click here and that will basically open client usage, React query integration, server components.
So this is where we are going to start. Great! So first of all, we're going to need to install all of these packages. Trpc-server-at-next, trpc-client-at-next, trpc-react-query-next, and then tan-stacked-react-query, zod, which we already have, or maybe actually we don't have zod. And basically, we're going to have to install all of these things.
So I'm gonna go ahead and do them one by one because I want to see the specific versions of this. So I'm gonna do npm info like this because I want to see the current next version which is 11.0.0-RC730. So let's go ahead and do that. One add at the RPC slash, is it server? There we go.
So at tRPC slash server at 11.0.0-RC730. And I would recommend that you follow, you know, exact versions as I'm using. And I'm pretty sure that all others are going to be here as well. So let me see, TRPC client, yeah, all of them are 11.0.0 RC730, but I will check all of them just in case. So that is TRPC slash client.
Let me just confirm it is trpc slash client. Okay. There we go. Then the same thing for trpc react query. So let me go ahead and check with npm info.
The latest is this one. So npm, my apologies, bun add, add trpc slash react-query at 11.0.0-rc730. There we go. Then we use the latest version of 10-stack React query. It's pretty important that they match, right?
So what I'm going to do is I'm going to do the same thing. Info for 10-stack React query at latest. Let's see. This one is, I'm not sure what should I be looking at here. How about I just visit npmjs?
Let me go ahead and search for it here, 10-stack React query. This one, so 5.65.1. That's the version we are gonna be using here. So run add 10-stack react query, 5.65.1, like this. And let's see, what else do we have to do?
We need Zod, client only and server only. Now I don't think these matter too much so we can just add all of this because you can see their versions so 3.24.1, 0.0.1 and 0.0.1 here as well. If you want to you can specify this version specifically but I don't think any of these can introduce any too much of a breaking change, right? Great, so let me go ahead and go inside of my package.json here, just to confirm my changes. So I have 10-stack React Query 5.65.1.
I have trpc client which is 11.0.0-rc730 and all the other TRPC packages like React Query and Server are exactly the same. My client only is 0.0.1 and I have also added Server only which is also 0.0.1. Now let's continue with the docs here. So first of all, it says to start with creating a TRPC router. So let's see if we can do something like that.
Yes, you can just click on View Sample Backend and you can just copy this entire thing. So go ahead inside of your source and inside of here go ahead and create TRPC like this and inside create init.ts and you can just paste this inside. So it's going to import initTRPC from TRPC server, it's going to import cache from React, it will create a very basic TRPC context. In here they just give you an example, like a user ID that you will destructure from your auth endpoint, right? And they create a basic trpcinit project here, and they export some procedures and some factories, which you will be able to use later on.
So make sure that you have this very simple init file. Let's go back to the docs and see what we have to add next. So we have trpcinit.ts, and now we just have to create like a basic hello route here. So we're gonna do that inside of trpc folder. We're gonna create routers and then underscore app.ts.
So let's just copy this here. Instead of trpc we're going to create routers and inside of here an underscore app dot ds and just add it here. And you should have no errors here because we have the base procedure from here, we have create TRPC router export from here, and we just have a very, very basic, you know, hello procedure. Base procedure means your normal public procedure. The input here is basically a Zod validation of what this procedure expects to receive and this is what it will return.
So we just have a very basic API endpoint here. So we can close the sample back and I believe that's all we have to do here. My apologies, not all we have to do. We also have to properly set up our app folder API trpc and then the catch route here. So let's go inside of our app folder, API, and let's go ahead and see.
So we have to create slash TRPC, my apologies. So TRPC, and then we need to create dynamic TRPC and then inside route.ts, like this. And we have to copy this, and we're going to have to fix this because they are using this tilde as the alias, but we are using the at sign as the alias. So we need to create the RPC context from TRPC init, which we have right here, create TRPC context. And we need the app router from TRPC routers app right here.
So that is our basic setup here. And now that we have a minimalist backend setup here, right, I think we can finally close this. There we go. And now we can go ahead and continue with the setup. And that is to create a query client factory.
So let's create a shared file inside of our TRPC folder called query-client.ts. Let's go ahead and do that. So inside of our TRPC folder, we are going to create query-client.tsx. Actually it says .ts so let's call it .ts properly. And let's just copy this and put it inside like this.
Looks like we are missing the module superjson. Yeah, I'm going to comment it out for now. You can comment it out as well because you can see it's commented out here. But we are going to enable this later. So it's okay, it can be commented out for now.
So a very simple query client here. This isn't DRPC specific, this is 10-stack react query specific. All right, so we have our query client factory and you can read more about some default options they have set here. I decided not to modify anything here. I was quite satisfied with whatever were the default settings.
One thing that we will change is we are going to enable data serialization. That's so we can safely pass things like date between server component and the client component. If you don't serialize your data, you will not be able to do that. So that's why they prepare the SuperJSON for you. Besides here, we're also going to have to, I believe, enable that inside of TRPC in it.
There we go. Inside of here, we also need to define the transformer, but we're going to come to that in a moment. Great. And now we're going to have to create a TRPC client for client components. So what does this mean?
Well, this brings us back to this example right here. We're going to have two TRPC instances. One will be for prefetching. So this TRPC right here, let me grab my pen. So this tRPC right here will be a server instance of tRPC and this tRPC right here will be a client.
I have no idea why that has darkened but basically this one here will be a client instance of tRPC. So now we need to create both of those. This one will come from import tRPC slash client and this one will come from import tRPC server. So let's go ahead and first create a client one. So this is quite a long one.
I'm of course going to pause my screen in case you want to type it out, but you know, you can also find it in the documentation or In the source code. So let's create the TRPC slash client dot DSX client Dot the SX like this and I'm gonna go ahead and just you know show you a bit so make sure we mark this as use client so we can mount the provider from a server component. These are our imports make sure you are getting no errors here specifically for this relative imports so if this is red it means that you put your client.tsx in an incorrect place, or your router, something is incorrect. If everything is inside of the TRPC folder, there should be no errors here. After that we create a TRPC React instance here and then we simply combine this with our React query instance here.
So basically this is what we are going to call for our client components right here. And this is where we're also gonna have to enable our transformer. A few gotchas here is, well, this part. So they use the Vercel URL as the environment variable. If you choose to deploy somewhere other than Vercel, you will obviously have to change this.
You can change this in a couple of ways. It's not that difficult. You can also use process.environment.nextpublicappurl and then inside of your environment.local, you would simply do next public app URL. By default, inside of here, it's gonna be localhost 3000. And then when you deploy, you would change this to be, you know, your actual application, which would be www.codewithantonio.com, right?
That's how you would do it if you are not deploying on Vercel. But in case you are deploying on Vercel, you can just leave this to be Vercel URL and let it fall back to localhost 3000 when you're in development and everything's gonna be just fine. So in order to complete this tutorial, I would recommend just deploying on Vercel because it's super simple and it's guaranteed to work. And then if you want to explore it yourself, just add a little to-do here. Modify for outside Vercel deployment.
Just a little note for yourself in case you plan on experimenting with this later so you don't get confused. Oh, why is it broken all of a sudden? And obviously this is also important. This get URL leads to slash API slash DRPC, which is obviously targeting our app folder app.drpc, which we just created right now. So if you for whatever reason decided to name this something else or perhaps made a typo here, make sure to fix it.
And to be specific, you need to change it here as well and you will also need to change it inside of this client.tsx. Great! So I hope that I've shown you enough of this file so that you can write it yourself. You can also find it in the documentation, you can find it in my source code as well. And now that we have finished this step, I believe what's left is to create a ERPC caller for server components.
And this is where the magic happens, right? Usually, not single other RPC had this solved, right? We were simply not able to natively call an RPC instead of a server component, which is basically this part, right? We were not able to do this. This was always just a normal fetch or API request, which loses all the headers and has no idea which user made this call.
But thanks to this magic of the tRPC caller, we can finally do that. So let's create tRPC slash server dot TSX on the same level as client. So server.tsx and let's copy this. Let's add it inside. Make sure you import server only in the beginning.
What this will do is it will throw an error, I think both in a local development and in production, I think it will even prevent the build from happening, if it detects this file being imported in any way, you know, even abstractly, so without your explicit knowledge or approval, it will throw an error saying, hey this file somehow found its way into a client side and that's dangerous, you can't allow that. So this is to ensure that our server-only TRPC instance can only be called on the server, so no malicious requests can be made. Great! So this one is quite simpler. Again, just confirm you have no errors in this relative imports and this new query client should now be used here as well.
Great! So, so far you should have the following the TRPC folder, the routers with a very simple hello base procedure, you should have a bit larger client.tsx component here, an init file, a query client, and server.tsx. And you should also have app API trpc trpc route.ts. And now you can finally use your API. In here they have some examples.
So how about we go ahead and try and free fetch hello here. And now we're going to try out all of these examples. So first of all what I'm going to do is I'm going to do bun run dev all. Remember we have this new dev all command. We are no longer running just the dev.
So I will just try to load my app, you know, just to see what the state is. So this one says, I will load videos in the future. How about we go inside of the app folder, home, page.dsx. And let's do something simple. Let's mark this as use client, like this.
So this is now, if you refresh a client component. And now what you should be able to do is you should be able to extract data from TRPC, which you will import from TRPC client, this is this big component, trpc.hello.useQuery. It expects a message, I think. Let's see, what does it expect? A text, all right.
So let's just pass in text, Antonio, like this. And then I will say this client component says data. And is it data.greeting? My apologies. And you can see that he's already put a little exclamation question mark here.
So let me go ahead and try. Oh, yes, I think we forgot one important thing. How did I miss that? And let's see, how did I miss that? We created this for client components.
I'm pretty sure, oh yes, mount the provider in the root of your application. Okay, so that's a big miss by me. Let's go ahead and do that. So we're gonna go ahead inside of our app folder and let's go inside of layout.tsx and inside of body let's add trpc provider and wrap the children inside of that. So trpc provider comes from trpc slash client.
Let me just move it here. So make sure that you have imported the trpc provider. It should be this component right here. Great. And make sure it's wrapping your children.
So you're doing this instead of the app layout, root layout. Now go back instead of home page.tsx. And I think that now it says client component says, hello Antonio, right? If I change this to Antonio2, it says, hello Antonio2. And now the way I refresh is I use this, I'm not sure if you can see, but I use shift command R which basically clears my cookies and my cache, right?
So I always do that because if you just refresh, sometimes it will have cache and you won't really see the loading happening. But you can see how right now, it's always kind of loading this. This is your normal, usual way of loading data. Nothing special with this. Now, let's try an alternative method, which I was talking to you about.
Let's remove this useClient and let's go ahead and instead of importing trpcClient let's import trpcServer. And what we can do here is first of all we can mark this as an asynchronous function, for example. And we can do data, PRPC, hello. And let's see, do I just call it like this? I think yes.
Text, Antonio. And we can just await it. And then right now, it will be the same thing, except I think we don't need this, right? So you can see that now what we're doing is we are literally fetching on the backend. So this is a server component now fetching.
You can see how we await here. So yeah, once we await, of course it's going to exist. There's no doubt about this. And I just remembered one important thing. I'm sorry, but I have to stop here because some of you might have some issues.
Let me just bring your attention to one thing. I promise we're going to come back to what I was demonstrating, but something did happen to me when I initialized the TRPC and I wasn't sure how to fix it exactly. In case, when you hover over your data here, you should be seeing data greeting string. When you hover over text, you should see text string. When you hover over hello, you should also see all of these proper types.
What can happen is that you are constantly seeing any. I'm gonna try and find if they have some troubleshooting for that. There we go. It doesn't work. I'm getting any everywhere.
If that's happening to you, you should go ahead and read this part right here and try and do these things. If you followed the entire setup the same way I did, it will probably work, but this is what finally fixed it for me. It was adding this to, right? So typescript.tsdk to use this typescript and typescript enable prompt use workspace.tsdk. Let's add both of those to our vs code settings.json.
So I promise I'm going to come back but this is quite important because Some people will stop watching here and try to debug themselves and perhaps they won't know that I explained the fix in a moment. So let's add .vs code here and settings.json and just add them here. And if this opens up, simply click allow like this. And what you can do is press command shift P and then just reload window just so it kind of resets the entire thing and go ahead and visit your source app home page.tsx And you can see that now I'm still getting my types here, but in case you were getting them as any, this will most likely fix it. But even if this worked for you initially, if the types were okay, I would still recommend having this because you will commit to this and then your colleagues who opened this project will have the same settings and then they're not gonna have any problems as well.
So that's one troubleshooting issue that I had and it was fixed immediately once I added this. And you can see that they also highly recommend committing this file so the colleagues can also get the same experience. All right, now let's go back to our example. So we just learned how to use tRPC purely on the client. We learned how to use it purely on the server, which is this, but how about our pre-fetching solution?
How about a hybrid between those two? How about leveraging the speed of server components, but leveraging the familiarity and the interactivity of client components right now. Because we can't really do much with this. Sure, this loaded obviously faster than the client side, but what exactly do we do with this? Server components are not that interactive.
We can't even add a hook here, we can't add on click, right? It's a bit more complicated to work with it. It seems like everything we gained with speed we lost with interactivity. So that's why we are searching for a hybrid solution to get the best of both worlds. Let's do that now.
Instead of actually expecting any data here, we're going to change this to be void hello.prefetch, like this. Keep in mind that I'm not exactly sure if this needs to be asynchronous or not. And even more, if you don't make it asynchronous, it's not gonna throw any warning. Unfortunately, I can't exactly tell you if it needs it or not, but in my project, I wrote async everywhere where I'm using prefetch, right? So I would recommend you do the same thing.
And now what's happening is that we are not using TRPC on the server to get the result in a constant and use it. We are using it to populate our data cache on the server side and then allow the client component to use pretty much already loaded data. That's what we are trying to achieve. So what I'm going to do is inside of my home page here I'm going to create a little client.tsx and I will do use client here. I will import trpc from client like this and I will export const you const page client component like this.
Page client. And I will import page client from .slash client like this. So now it should just say page client here but if you take a look inside of your project here, if you do a hard refresh here, oh yeah, so nothing's going to happen yet but the moment you add const this time inside of square brackets, not curly brackets, because we will be using trpc, hello, use prefetch query like this. My apologies, use suspense query, not prefetch query. Let's see, what exactly am I missing here?
An argument for input. If you try now, page client says, data.greeting. First things first, you will already notice that this is always loaded. There is no possibility of this being null, right? Because this is a suspense query.
We already started loading this on the server, but we are going to finalize the cache and everything on the client here. So right now you can see that we are using this as a client component. So we can now go ahead and add use effect and all of the other things, you know, which we were not able to do in the server component, but we are still leveraging the speed of server components. Because remember in our first example, which was just the TRPC hello, and it was just use query, that was a bit slower. For a second it was empty, right?
And then it got populated. So when we combine the two, we get the best of both worlds. But This is not exactly a finished example. There are some things missing here, and that is the Hydrate client suspense and the error boundary. So let's go ahead and add Hydrate client from the RPC server.
Let's add suspense from React. And let's go ahead and give it a fallback, adding loading like this. So now if you do a hard refresh, I think this query is not really complicated enough to ever show the loading state but now we do have a suspense which will show loading. We also need to add an error boundary here and for that we can use react error boundary let me just go ahead and see if this is the one I want to use yes this one so let's use 5.0.0 React error boundary, bun add React error at 5.0.0. Let's import it here.
So import error boundary from react error boundary like this and let's give it a fallback error right now and nothing should change really but if you go ahead inside of your TRPC routers app folder and if you go ahead and throw new TRPC error. Let's see, I think you can just select code, bad request. So this is also Another super cool thing about TRPC is that you have this strictly type errors, right? So you can just add not found if you want and it will be typed. So now you can see it says loading, it will attempt to load it a few times.
And then I think after three or four retries, it will fall back to error. So this is the server-first data pattern that we will be trying to achieve throughout this project. We are going to leverage the speed of server components to prefetch the data and then we are simply going to let the client component not have to fetch anything initially. It will just have the data ready inside And for any loading states or errors, we're going to leverage the suspense and the error boundary. And yes, it will still have a loading state, but these loading states will be much, much shorter than in comparison, if this was just, you know, use query and then we would have to be structure data and is loading here and then we would do if is loading right we would have to do all of those things here that's going to be much slower especially noticeable on larger queries than this hybrid combination of both of this.
And now there are a few, you know, tips and tricks that I just wanna end the chapter with. Every time you use useSuspense query, you have to have an equivalent prefetch here. Same thing is true if you do use suspense. I'm not sure if I can do it now. Yeah, I cannot do it right now, I think, because I'm missing the proper returns to create this into an infinite query.
But if you are prefetching infinite, you also need to suspense infinite query. You have to be careful about doing something correctly. Also, for example, if you have some input inside of here, if you suspend query Antonio2, but you prefetch text Antonio, that will not have its effect, right? Let me just remove the error that I throw here and remove the import from here. So if you refresh this, now it works because this is super simple, but it's actually not leveraging the prefetching that I was talking about.
Because this doesn't make sense right now, because all that these queries are doing are just returning back the input. But imagine this input was a video ID. We would first have to go to our database and load the video, right? So imagine if you have prefetched video ID 1 and then you suspense query video ID 2, that would completely lose its purpose. It would not be able to prefetch what it was supposed to prefetch.
I hope that kind of made it clearer. We currently don't have any authenticated examples, so I can't really show you any other gotchas here. But basically, in case you use useSuspenseQuery for an authenticated procedure and you forgot to prefetch, you're going to get an error that the procedure has folded back to client and it's unauthorized. That's because the cookies from the header which were supposed to be prefetched here were never passed inside of here. So yeah, it is kind of, you know, not exactly perfect, but there is, I mean, when I say not perfect, I mean, you have to be careful.
It works, but you have to be careful with how you're doing it. But I will just pause the video for a second and I will try and find one GitHub discussion where they are finding a way to make this a bit more stricter so the application itself will warn you if you're doing a mistake like that. So this is the discussion that I was just mentioning. Basically, this is one of the authors of the TANStack React query and inside of here they are introducing or discussing this exact issue which I just mentioned. If you forgot to prefetch and then if you use useSuspense, it will not work, but it will also not throw any errors.
So the main problem we are seeing with prefetching is code dislocation. I guess that's the proper name for it. So if you just call ususpense query in your component and having it work, it's very convenient. But without a compiler like Relay, it will not be possible to extract those data requirements and trigger prefetching somewhere else automatically. So what we're left with is duplicating what we do.
Have a component called useSuspendQuery with certain options and use the same option in your route loader to do prefetching. So that's what we are currently doing. For every useSuspendQuery we need an equivalent route loader to prefetch that query. Obviously there are some issues with that. Here is a proposed solution.
They are working on query strict mode component which I suppose you would wrap around your application or you will most likely just add it to for example TRPC client. You would most likely just add it inside of here. You would wrap the query strict mode and it will then warn you if you are missing a prefetch or if you have an unnecessary prefetch. So I think that's a very very cool solution here. You can read more about it so just go ahead and Google this.
Even I left a comment here because I noticed that if I call prefetch infinite but combine it with use suspense query instead of calling use suspense infinite query in that case there is also an issue here but this does not really fall under the same problem as they are trying to solve here, and I did get an answer for that. But yes, you do have to be careful about that. And I'm going to try and emphasize this throughout the project the more we build, but I hope that for now it kind of is a bit more clearer than it was in the beginning, especially the first time you saw this diagram. I hope you now understand what I'm trying to do. So basically we're trying to get the best of both worlds.
We are trying to get the speed of server components and the interactivity of client components. We are going to exclusively use server components as route loaders and nothing more. So server components will just prefetch the data and then client components will have that data ready to use and it's going to be very very fast for the end user. Great! So I think we successfully enabled trpc.
What we're going to do in the next chapter is we're going to combine our clerk authentication with trpc and we are slowly going to organize our routers and procedures in a nicer way. Great, great job!