Server Actions: NextJS 13.4's Best New Feature
VloĆŸit
- Äas pĆidĂĄn 11. 07. 2024
- Server actions make it a lot easier to fetch additional data from the server, or make mutations on server. Just add "use server" to a function and now it's a server function that you can call from the client as easily as just calling the function and awaiting the result. Check it out!
Code: github.com/jherr/njs13-server...
Server Actions Documentation: nextjs.org/docs/app/building-...
đ I'm a host on the React Round-Up podcast: devchat.tv/podcasts/react-rou...
đ Don't forget to subscribe to this channel for more updates: bit.ly/2E7drfJ
đ Discord server signup: / discord
đ VS Code theme and font? Night Wolf [black] and Operator Mono
đ Terminal Theme and font? oh-my-posh with atomic and SpaceMono NF
0:00 Introduction
0:52 Creating The Project
2:53 Server Actions For Forms
7:38 React Without Javascript
8:45 Monitoring The Form Post
10:53 Using Transitions With Server Actions
15:05 Using Server Actions For Queries
19:36 Server Action Caching
21:09 Outroduction - VÄda a technologie
I always like your videos, explaining hard concepts through simple words and practical examples
Thank you for keeping up with the updates! Super helpful.
You literally answered all my questions on this topic! I'm very grateful, thank you!
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.
Great tip!
@@jherr Do server actions trigger the middleware in NextJS?
@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
Awesome! I hope you will continue with such videos about NextJS 13.
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?
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 czcams.com/video/sdKFEo6978U/video.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!
best server action tutorial on youtube.
Good Work.
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!!!
Thanks! And you got me beat of English with the use of "didactic". :)
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.
Right, a server action is a function that is sent to client components and which gets run on the server when the client component calls it.
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.
thank you
Very good video, thank you !
This was great, Jack! Classic pokemon lol
great video, really thankyou
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!
how do you handle mutations? I am using SWR but I am having hard time dealing with form mutations
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.
Very cool. Can you share the workaround for next auth?
Please can u share how u setup the next-Auth workaround inside server action. I have been trying to figure it since yesterday.
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?
Up
Up
Most awesome video about server action
Great video as always! Thanks!
Thank you!!!
I was waiting for app dir to be stable before I start using next 13, now I'll be waiting for server actions to be stable. Good times.
Can't wait until NextJS becomes an MVC framework :D
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)
Do you have a "Props must be serializable" warning on the form post with transition's AddButton's props?
Great Video Sir, can you please list down VS code extensions you use?
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
Really good video. thank you! How can I empty text input after submitting form using server action?
You are the best!!!
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
thank you!
"Let's re-enabled javascript, because we are not crazy." Lol Love it.
Wonder if we use Axios instead fetch it will still cache for us or not ?
in last example, could the initial list of names of pokemon be pass from props from the server component?
This is amazing! Can you do a signin form submission that works with useformstatus?
Awsome video!
What is this from action attribute assigned a function? Where can I read more? As per the docs it should be string URL
how would this work on vercel?
I assume these are serverless.
So you would get different todo lists?
Is useFormStatus scoped to the form it's called or is it some global thing and it's going to disable all buttons on the page if any form is submitted?
Does Qwik's routeAction$ function perform the same actions as this one?
Could you show us some react-query patterns with the new app directory?
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's no need for react query with server components model
We need this
Is react-query still needed? As a heavy user, I dare to say but... I see a pattern here :)
I don't know what you would need react-query in a server components environnement. The state is the server.
nice video. what browser is that though
I really love your videos, by the way how did you pin the network tab at the top of arc browser?
That happens automagically when you open up a localhost like (at least it does for me)
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.
"Client" components are run both on the server and the client.
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?
Can u make a short tutorial website in next 13.4 Combining all these new features. That would be very helpful.
Thanks
how do you clean the input values after submitting the action?
Could you please show with database usage in actions?
Because it is a more tricky thing, when you need to open a connection, then close it ?:)
Hi!, do you have any videos with adonis js framework?
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?
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 ? đ€
No worries. I said "it runs on the server as opposed to running on the client".
Aaah , đ I heard it âas well asâ, thanks for the clarification, you are best â€
The thumbnail looks 3d, pretty cool effect. Was this intentional?
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?
Hey Jack thanks for the Zact recommendation, it rocks. (also for the vid)
Tell me it is PHP without saying it is PHP....
WHAT HAPPENED HERE???
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.
Coule you show us how to integrate swagger with the new app directory?
I can only aspire to have hair this good.
Does revalidate path reloads whole page?
Maybe a little bit off-topic , but what is that vs code theme?
I just love it!
Look in video description
Can we use App Router for production ready application? Or it is too early to use app router and we should use pages router?
I think you can now. Itâs not going anywhere, itâs definitely the future. There are some rough edges but the core features are stable.
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?
Not enough information to make a recommendation on that.
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.
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.
The mechanism is a straight fetch to the server. So the same security issues apply to other NextJS based API endpoints.
Nice đ
Huge win for progressive enhancement in React!
No useOptimistic demo? đ€Ș
Maybe in another one.
Why is there a white flash when you revalidate the path?
yep, looks like old fashioned page reload
Awsome đ
Can server components help, we get rid of useEffect?
So how can we make form validations the component is server
Are actions only for native form tags or also for libs like MUI and Chakra?
You do know that any UI lib uses native HTML elements in the source code? So the answer is yes, but then you job is to figure out the imprementation.
Using actions for the search example was interesting verses just using an RSC. Probably a video in that as to pros cons.
What do you mean with "versus just using an RSC"?
Itâs like MS Ajax from 2008 but for react!
What's your terminal?
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.
I'm not actually sure it reloads the page.
Like it.
Does this mean I can share types with the client and my server without any extra steps? đ€Ż
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?
dont try to put a function inside a string đ„¶đ„¶
Can you please do a video on PWA with next.js 13.4
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
Please give a example of authentication jwt in new nextjs 13 ! đ„ș
how do you think qwik vs next 13.4. Seems one for performance, another one for community, it is very hard to choose for next project
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âŠ
how come after reloading, the variable storing the todos has two todos? My first thought is after a reload, the variable resets to its initial state
Reloading the page? That's not changing the server state. The server state is what has the todos.
â @@jherrohhh got it, so that variable lives in the server, reloading the page has no impact whatsoever
Where is the todo data being stored? If I can access it across browsers and you said its not session storage then how?
It's in memory on the server.
We want video of your studio which is very peaceful lovelyâ€
im confused couldn't we do this in the past?
are these server functions some how vendor locks you ?
Kinda, but they could easily be replaced with API calls.
Cheers Jack. Is it me or is revalidating causing the whole page to reload?
It's just invalidating the cache.
action is still string required, so weird.
Is this going to replace tRPC? What's your thoughts on this?
To what extent do you think this obviates react-query?
In some cases, sure. Though... I think you could use react-query to monitor the promise returned by a server action function. Hmmmm...
I don't understand how writing "use server" can change its behaviour. What's the magic behind that?
âšCompilation âš
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.
@@dealloc Thanks
Must server actions always be POST?
Nope, GET with query works too.
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.
I see, seems like it'll always be POST. Thanks.
I think Remix got server actions right - not convinced by Next's approach at the moment.
Awesome video as always...but this is kinda gross tbh. I came to React to get away from Rails and I may go back to Rails.
I'm having 2008 flashbacks. Next is becoming exactly what all the old MVC frameworks were. I'd advise everyone to look at why we moved away from them.
My question is, how revolutionary is this, why is this released now and couldnt be done earlier? And whats the use case for this?
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
I heard server action is leaking secrets.
I think it's possible. I haven't vet that fully yet myself.
php > react > back to php
thanks,
for me it's better to split shorter videos,
transitions explanation brain already been slept
tanks please git hub?
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.
Eeerrrrm. But we have something like this in Sveltekit and it works better and safer than this...
Then use it?
but svelte has less jobs than react
ok?
I didnât see a single real example for application in the video, some fictional things, and I donât understand what is wrong with this innovation
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.