I recommend for thee `server actions with queries`-part that you: 1. declare your server action in a separate file and mark the file as 'use server' in the top 2. export the server function 3. import the server function IN THE CLIENT COMPONENT 4. profit. There is no need to pass down the server action as a prop to the client comp, it can be directly imported as well.. A server action can even pass down a react component as well.
@claus4tw yes that is what i am trying to do but i found something which i dont understand i have my problem in the comment i am pasting here also if you can guide me little this was my question i am following same thing with little different approach and i would like to know why it behaves like this so i also have a little todo project trying to understand server action mostly "use server" and "use client" here is my setup i have 4 files which are as follows: submit.ts => server action function Form.tsx => client component Tables.tsx => client component => to show all todos todo.ts => just a variable to store data todo.ts => code interface todosContract { todo: string; date: string; } const todos: todosContract[] = []; export default todos; and main page.tsx => server component what i have found is when using client component in form and table i cant directly import todo.ts to map data when imported submit.ts and applying to form action , i see on server seide data is added todos but its not reflecting in table, i mean on client side data is always empty i found when i send submit.ts as props to Form.tsx from main page.tsx for action this resolves the problem i can see the data in table then, i am not sure if this is right approach or not i hope you understand what i am trying to say. i would really like some insight on this UPDATE does this mean when i am doing "use client"; import todos from '@/app/todo/todos'; does that mean this todos when initialised as this was empty initially and i am using "use client" that means its a different instance now on client side then of server side hence when server action push data to todos on server side, client never get updated that as it was treated as different variable for client side. just a thought
i'm not going to lie. it's kind of magical to see server code running in response to user/client interaction. this is the type of thing that becomes hard to wrap your head around and i hope the next team can disspell any confusion around it with good docs and consistent patterns.
so am I, cause now I can't imagine how to use these ui framework providers (which automatically turn your app into client side app), axios apis and so on in prod
Yes, I am struggling to do 'useState' local error handling on form inputs before the server action is triggered. In @hamedbahram's video ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-sdKFEo6978U.html, he defines an async/await client function in his form client component - which awaits response of the server action function, for me React produces a runtime error: 'async/await not supported in client component'?? @jackherrington Thanks!
I went all on in server actions when they came out. I rewrote large parts of an app I am working on which originally used the t3 stack and trpc. Now I use drizzle-orm, server actions, zod, next-auth, and react-query and so I have end-to-end typesafety including validation, authorization and no codegen in between. Things are still a little rough around the edges (next-auth needs a a workaround to validate the session because getServerSession doesn't work yet) but it's certainly a lot of fun!
I'ts great to hear that. I'm currently working in a project, we are beginning to add some type of authentication, I tried to implement Next-Auth because I was familiar with it in the past versions of NextJs, but right now I'm having so much problems to implement it. Can you please help me ? Like, how do you made it validate the session for example ? If you have some explanations or articles, I would be so much grateful. Thanks for your time !!
I use react hook form for my forms as most of them are rather dynamic and I need validation while the user fills it out. Therefore I don’t use form actions at all and instead dispatch my mutations on submit. I loose progressive enhancement but I gain the ability to use react-query which has a useMutation Hook that I make use of. That hook takes a mutationFn which is just the server action.
One important note: Make sure to put them in a different file/fetch SECRETs inside it. server actions are in alpha stage, so they are not suited for production, and they currently have a security vulnerability that happens if you pass the action as a closure. Something like this: export default async function Page( ) { const c = await fetchCredentials( ); async function serverAction(fd: FormData) { "use server"; const items = processStuff(c.userSecret); } } Possesses a security vulnerability since Next.js will include it in the headers (maybe from the headers, I know it is possible to view the credentials in the HTTP request from the devtools). If you have any code using this style, you need to be careful, for now you need to move the action out of the page component or fetch the details for now: async function action(fd: FormData) { const c = await fetchCredentials( ); const items = processStuff(c.userSecret); } export default function Page( ) { return ... } Once server actions become stable, they can be used as closure just like client component functions, but for now, you have to do this prevent leaking credentials.
And if you pass it to a form action it will also add it as hidden elements. Hidden inputs are useful to keep state around from page request to the form request, which means it likely was meant as a "feature", but a feature with a huge footgun.
Hey Jack, love the video! I am still trying to wrap my head around why we would use server actions in a server component, to lets say call the database, when any normal function in a server component is ran server-side already.
Being a web developer for 15+ years, I’m confident that the best way to build apps is building a decoupled API first. It allows you to swap out either the front end or the backend independently. Less vendor lock in.
@jherr what do you think of this? Wouldn’t Server Actions create the same problem: we had crappy APIs in 2000s because the web apps were not created API-first but rather API-later?
Although English is not my native language and I am not fluent, your pronunciation and didactic approach are really excellent, which allowed me to understand everything. Congratulations on a great job!!!
I probably will, but I have to say I'm so surprised at how poorly these videos are doing. NextJS is usually a home run content wise, but people seem put off by it?
This would require client components to use, but you can wrap the query client in the root layout, and work from there, what i normally do is this method, and then use context inside each route layout to have easy access to data on client components
There is one thing that gets my attention and is that new technologies always come along to reduce the gap between users and data. We want instant access regardless of the device and bandwidth. However, a delay is always a case and is always considered, some kind of loading state, or transition. It's like the dog chasing its own tail metaphor but on rolling blades. (random comment)
I have a question about revalidatePath fn, do you know is that possible did update on few pages in Server Action? For example : revalidatePath('/home'); revalidatePath('/about'); Or it is possible on ur path right now? I try, and it not work for me I still have cached data on other link, may be I miss something or just not understand correct. Didnt find answer in docs next 13.4
Hi Jack, when I assign the server action to the form's action prop, it shows this error: `Type '(data: FormData) => Promise' is not assignable to type 'string'`. Can you give me some advices to troubleshoot it?
Is it possible to use an abort controller with server actions? With a search form, if I debounce the input but send the request automatically on keyup, I'd like to abort any inflight requests to avoid race conditions. Is that possible?
I cloned your source code and run. But it had an error: "Error: backingFormData.forEach is not a function" when submitting the simple post form. Would you like to recheck it?
Thanks for your great content. I have question about server and client side components. Since every component inside the app folder is a server component and executed from the server first. When I mark a component with "use client" as a client component and run the program, will that client component also first pre-rendered on the server and then rendered on the client for hyration as well ? I ask that question since when I write a console.log("hello") inside the client component, it logs both client and server sides. I assumed that the client component ( which is marked with "use client") only runs on the browser instead of pre-rendering on the server.
When you pass a server action as a prop to a client component, does this pose a security vulnerability? I'm assuming next has thought of this and implemented safeguards, but I'm curious how it's done. I would assume something along the lines of interpreting the server action as a fetch to the virtual server action endpoint.
I'm getting a typescript error when I try and pass my action function into the form. " Type 'Promise' is not assignable to type 'string' " Any ideas how to fix this?
Hi Jack! Great content! Im playing around a little bit with server actions, and everything works in the happy path, but... how can we manage validation errors? For example, the todo has to be longer than 4 chars or to make the form empty after submit, thanks!
You should probably validate that client side using something like react-hook-form and use server validation as a last resort. In the action, I'm not sure what throwing an error would do, maybe generate a 500? And may that would come back as an exception on the client? That would be cool. Otherwise you could respond with an object that has a success flag and appropriate error messages.
@@jherr Hi again! Sorry for the late response, but I was playing around this concept during a couple of days and I think I have some meaningful insights: Context about my objectives : - I wanted to use my domain entities to the single source of validation either for client and server operations - I wanted to dont couple my react use-cases components with the "use server" function that is clearly coupled to nextjs (with the usage of revalidate path) And I ended up with the following approach: - The "use server" function can return plain objects (as needs to navigate through the http request) so, im returning in case of mutation a type "undefined | error" so I can handle things like "unexpected error" or "username already taken" that is imposible to handle client-side. - This treat this function the same way I treat services/repositories, I use dependency inversion to be able to mock that function at test time As note: If you throw on the "use server" function, the request will be a 500 and you can catch that error at client side, but as that error is unknown, I preferred the approach of sending it as a valid payload of the request. Anyway, I think will be a big challenge for big projects the alignment between the different teams on how, where and when to use either client or server functions and do it in the right way without too much coupling and allowing the testing.
I really appreciate your videos thanks a lot I just have one question regarding using server action with a form, how can i show an err message on client in case an err occurred in the server action
Weird how useFormStatus is throwing me "Error: (0 , react_dom__WEBPACK_IMPORTED_MODULE_2__.experimental_useFormStatus) is not a function". Guess I have to settle with the loading page for now
Hey Jack, again a commendable work on the video loved it, Am I wrong or you said it incorrectly at 14:05 that server function runs on both server and client, I think they only run on server once invoked ? 🤔
In something like the PokemonList example, where there isn't any secrets involved, will you prefer to do client-side fetching (e.g. with react-query) or server-side with API routes/server actions?
I think it comes down to whether you need SEO for that page, if you want quick and dirty, no SEO involved then just use client. I doubt you will see real world difference fetching a pokemon list either client or server side, if you app is huge and the js bundle gets shipped to client is also huge then you may need to start thinking server side render to reduce that js file size to improve speed.
Because it's refreshing the page would it be possible to animated the adding of the todo? I feel like this prevents you from doing some cool animation stuff.
These are directives. A standard syntax of JavaScript (see "use strict"). These directives are picked up through static analysis and upon compilation split into files served only for the given boundary. For "use client" you have to specify it per file (not per scope, unfortunately) since it is a module boundary (it's served to the browser) whereas "use server" can be defined in both file and function scopes.
Same dilemma here -- undecided nextjs 13 vs qwik for my next project so have been developing same project in both to form my own impression and understand limitations for my specific use cases. I prefer Qwik in almost every way, considering framework alone, but lacks next/react ecosystem & community. Interestingly, resumabilty is what drove me to try qwik (out of curiosity), but not a reason for me to stay since can achieve similar page load times w/ Nextjs w/ a little extra work, The biggest thing I like about qwik over next 13 app router is you don't have the client/server divide for interactive (i.e., no need to breakout a component into "use client" just because has onClick), and as great as the nextjs/react ecosystem is, support for appdir is limited or non-existent in some cases. E.g., if want to use headless ui, your app effectively becomes client rendered by the time you're done, and trcp is not supported at all (although server actions addition make less needed if OK using alpha feature for time being). After using both frameworks side-by-side for a few months now, I'm strongly leaning towards using qwik, but it is not an easy decision for me.
@@RolandAyala thank you for detail analysis on this. Yes, both of them has their own advantages and you are right. It is quite a bit annoy in splitting use client in some interaction. But to some extend , next13 has its own convenience. It’s hard…
Yes I got that semantically you could query for data using Server Actions. But how does it let the developer distinguish between a HTTP POST vs a HTTP GET request? E.g. in previous versions of API routes you could get that from the incoming request's 'method' parameter in the body of the handler function.
@@maelsoom I think you don't define that if you're using server actions. You're letting the system handle that distinction. If you want to control that then use a router handler instead.
Not very revolutionary because a lot of other frameworks have had this for a while. Not sure why it was specifically done now, just good to see. And there are lots of use cases for this for micro-APIs required to drive the frontend, like search queries, paging, form posts where you don't have direct access to the microservice APIs etc. etc
That "use server" syntax is hacky as hell. Giant turn off. Couple that with the security vulnerability in the pinned comment, I would HIGHLY recommend not using this.
I truly dislike "server actions". An API should be developed and thought out as an easily defined and maintained interface to the client(s) that use it. This is an obfuscation that makes that very difficult. ...no thanks.
How to use server this code const [coin,setCoin]=useState({}) const params = useParams(); const url = `ht**************om/api/v3/coins/${params.coinId}?tickers=false&sparkline=true`; useEffect(()=>{ axios.get(url).then((response)=>{ setCoin(response.data) }) },[url])
There is a Discord server associated with this channel. You can ask your question there. Please read and follow the #rules before posting. FWIW, useEffects don't run on the server.