How to access a D1 binding from a next.js tsx file (NOT .ts)?
In my next on pages app, I got a db call working on a .ts file but I'm wondering how I access that data within a tsx page? I've read all the documentation but I don't see any next.js examples of calling data within a .tsx server component, only from a .ts file (which I can't import bc of this error in the screenshot).
Open to any suggestions :PES_CryHug:
![No description](https://cdn.answeroverflow.com/1235930778404257953/Screenshot_2024-05-03_at_08.23.43.png)
17 Replies
I believe the issue here is that "use client" directive - you cannot call your D1 directly from a client component
Try using a server action for that
![No description](https://cdn.answeroverflow.com/1236092062504325130/Screenshot_2024-05-03_at_19.08.29.png)
@thipperz if I get rid of that directive though, I can't use
useEffect
and I'm not sure how i'd get that db call to be made on page load. Maybe there's another way to achieve that that I'm not aware ofYup you should not remove "use client". Instead, create a server action that calls the database and forwards the results to your client component.
A "server action" is an async function that is exported from a file that begins with the "use server" directive.
For example in app/actions/index.ts:
Then you can import this new function and use it from your client components. Notice how server actions act like a bridge between client components and parts of your app that cannot be imported from them (usually because of a "server-only" clause, that is useful to avoid leaking sensitive data to the client
Ahh ok I'm gonna try this, thanks
Let me know if it works for you
I think I'm close...
./actions.ts
./page.tsx
gives me:
![No description](https://cdn.answeroverflow.com/1236098069456486501/Screenshot_2024-05-03_at_19.32.10.png)
The data that you return from a server action must be serializable - what are u returning from your GET function?
Lol great question. I've been trying to console.log it to see haha
I got this from the docs at
https://developers.cloudflare.com/pages/framework-guides/nextjs/deploy-a-nextjs-site/#access-bindings-in-the-application
and also referenced the next.js db example call in this:
https://blog.cloudflare.com/blazing-fast-development-with-full-stack-frameworks-and-cloudflare
I never tried importing the GET method of a route handler before lol
I mean I have no idea if that code should work, but if it should, you could try awaiting the json method to finish before returning the response
await Response.json(data.results)
If this does not work, you could try moving that DB call to a .ts file and returning the results directly instead of having them being encapsulated by a Response
For example if you move it to a lib/db/index.ts
file:
Then you would import this into your server action and finally import that action in your client componentoh let's go
![No description](https://cdn.answeroverflow.com/1236108934574772245/Screenshot_2024-05-03_at_20.15.20.png)
axing the Response wrapper object in the return from the db call .ts file gave me some progress
man why on earth would that work
json is serializable right... that was the return object type. Weird.
hmm did you try adding the "await" I said? Like
await Response.json(data.results)
because I believe Promises are not serializableOk so I did a return await on the db call:
and on the actions.ts
and then the .tsx file:
oh im an idiot. Had to take it out of the
setData
function. doh
@thipperz thanks so much man, you were a huge help. Really appreciate it
you're a life saver lol
:peepoHappyhug:You're welcome!
I also learned a few things from your case lol
But I'm actually a bit confused about this:
Because I believe route handlers (any route.ts file) must return either a Response or a NextResponse object (?)