
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
How do I remove the blur effect from my CSS?
I removed but the blur is still there. Any ideas?
filter: blur(5px);
Does work for removing blur from modals?
backdrop-filter: none;
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:17 Hello, thank you all so much for making the time to get in here and for choosing this workshop over maybe some other ones.
00:00:24 So I hope you're excited about the topic.
00:00:27 We'll try to go over a lot of useful stuff while trying not to keep it too boring or too dull.
00:00:33 So I'm going to give my best to just make it somewhat enjoyable to watch and listen to as much as we can as we will be diving into some advanced topics
00:00:44 as well.
00:00:45 So I'll give my best.
00:00:46 I went ahead and my team as well.
00:00:48 I got to give huge props to them for preparing even the slides, the presentation, everything.
00:00:53 We're going to have some live demos.
00:00:55 We're going to have a lot of stuff.
00:00:56 So I'm really grateful for you being here.
00:01:00 And while people are joining, we can slowly kind of get started.
00:01:03 So I'm guessing that kind of the goal of all of you here is maybe seeing how we can better leverage Um, not only what Next.js is offering,
00:01:11 but what React is offering and then what Next.js kind of, um, simplifies and, um, creates a wrapper off of, right?
00:01:19 To better use the React, but therefore Next.js code in production as well.
00:01:23 That's kind of going to be the topic for today.
00:01:25 So diving right in React server components.
00:01:31 Probably the biggest talk of 2023 after AI.
00:01:38 If you've been on Twitter or X, you've probably been seeing people talking about it every single day.
00:01:46 Some people love them, some people hate them, and most people are just confused.
00:01:53 We have questions like, what is RSC as in React Server Components?
00:01:59 Isn't it the same as SSR?
00:02:02 Why is React turning back the PHP?
00:02:06 How does this all fit with Next.js?
00:02:10 And can I use it without Next.js?
00:02:15 Right now, that's a bit of a mess, but I'll do my best to untangle that mess for you.
00:02:23 So before that, a little self-introduction.
00:02:27 I'm Adrian, the founder of JavaScript Mastery.
00:02:30 We've posted a lot of different educational YouTube videos on topics such as JavaScript, React, and over the last year, a lot of Next.js.
00:02:39 And also I've been recognized as a GitHub star, kind of a position offered by GitHub for people that really try to give back to the audience and to people
00:02:50 focusing on education.
00:02:51 So I give my best to create over hundreds of project-based videos where we teach developers how to build real applications,
00:02:59 start to finish.
00:03:01 And I've been working with the new Next.js a lot, ever since it came out, almost using it in all of our YouTube videos.
00:03:12 We had it a lot, building real applications, teaching it in our Next.js course as well.
00:03:19 And it's completely new in Next.js.
00:03:21 From 13 to 14 and even further, there's a lot of new stuff happening with Next.js.
00:03:29 We also created the Next.js course right here that almost 3,000 people have joined.
00:03:35 And in this workshop, I'll explain what I've learned about React Server components and how they connect with Next.js in a way that's easy to understand.
00:03:46 So let's begin with a warmup on re-React server component era.
00:03:53 Things were simple and straightforward.
00:03:57 React was guaranteed to run on the client's browser.
00:04:01 Nothing else.
00:04:03 Simply ship big chunks of JavaScript bundles with minimal single HTML file and tell the client's browser to handle everything else.
00:04:15 The process, as we know it, the client makes a request to the server, which looks something like this.
00:04:22 The server responds to HTML and JavaScript bundle.
00:04:27 The client renders HTML and downloads everything mentioned in the JavaScript bundle.
00:04:33 The client executes that JavaScript and then paints the content on the screen.
00:04:38 This was surprisingly amazing web invention.
00:04:42 It still is, but like all things, it still has drawbacks.
00:04:48 Yes, even React has drawbacks.
00:04:50 The most important ones being performance.
00:04:56 The more JavaScript you ship, the longer it will take for your site to load initially.
00:05:02 And in today's world, the first impression is crucial to keep your users engaged on our websites.
00:05:10 We also must not forget about the low-end devices, where we presume that all users have top-notch devices, networks and browsers and trusting that their
00:05:20 browser could handle it.
00:05:22 Yet, not everyone owns the latest devices, and we can't overlook the fact that over time, we're not incorporating increasingly advanced features into websites.
00:05:33 So if you've experimented with Next.js during development, you might have observed that it doesn't perform optimally on MacBooks with Intel chips.
00:05:44 They're powerful machines, but new technology is demanding.
00:05:50 So as new technology evolves, so do challenges for users on less advanced setups that were powerful some day.
00:06:00 And of course, we can talk about React drawbacks without mentioning SEO.
00:06:05 Yeah, yeah, you heard it.
00:06:07 Multiple times that React doesn't play well with SEO.
00:06:11 It would have been amazing if web crawlers understood JavaScript, but unfortunately, that's not the case.
00:06:18 And with minimal HTML from React, our website doesn't get to properly understand SEO.
00:06:26 So to address this problem, Next.js implemented SSR, right?
00:06:32 SSR server-side rendering, this method involves rendering React on a server, generating HTML, and then sending it to the client.
00:06:42 The client is then responsible for rendering these HTML nodes and elements and incorporating the necessary JavaScript to enable interactive content.
00:06:53 It's important to understand that as of now, SSR can only render React components that are suitable for rendering of the server.
00:07:02 Components requiring interactivity, such as those with event listeners or dependencies on web APIs, aren't executed by SSR.
00:07:11 You can think of SSR as a method to create a blueprint of our website.
00:07:17 It generates and displays how your webpage will initially appear.
00:07:24 For example, consider the following scenario on the page.
00:07:30 We have a home.js file where we have a typical counter that you've seen hundreds of times.
00:07:37 I believe it was also featured in React.js docs as one of the first examples of using states when hooks came out.
00:07:46 How many of you were here for React 15, React 16 when we transitioned from class-based components to just hooks?
00:07:57 Feel free to let me know in the chat.
00:07:59 Not a lot of new generations of developers that are coding right now have been through that time.
00:08:05 Have you been here for that transition?
00:08:09 Yeah, it's crazy to think that some of us have started with class components and some of us, or some of you maybe, have never ever used class-based components,
00:08:22 which is a pretty interesting thing to think about.
00:08:26 So we have this example right here, and the result of the SSR output would be like this, where we simply have, welcome to my new Next.js app,
00:08:37 where we have the button and the counter.
00:08:39 That's the SSR.
00:08:41 An HTML page is produced here, comprising a list of elements and nodes representing the components on that page.
00:08:48 But what about interactivity?
00:08:52 All the states and event listeners are dispatched to the client and as JavaScript bundles, which the client browser loads and initiates the construction
00:09:03 of the virtual DOM.
00:09:05 The client compares the static DOM we received initially with the virtual DOM it will create using the provided JavaScript code,
00:09:13 and then determines if they properly match.
00:09:16 If not, it'll throw an error saying that many Next.js developers are frustrated about, which is going to look something like this.
00:09:25 A hydration error.
00:09:27 This entire process of reconciling the virtual DOM, which the client believes represents the page, with the actual static DOM that the server delivered
00:09:36 is called hydration.
00:09:40 And everyone's favorite, Dan Abramov, put it in this way through his mental models.
00:09:46 Before, so without the SSR, we have the React tree where we render components to HTML, we have the main JS, and then we bundle the code for interactions
00:09:58 like this.
00:09:59 And then after SSR, it's going to look something like this, where we have the server tree with the file system, databases,
00:10:07 internal services, and a lot of other stuff, and we pass props to the React tree like this.
00:10:13 Basically, a virtual DOM or tree created by the client, which looks like this.
00:10:20 Server, client, and now we have everything happening on the client as well.
00:10:26 Yeah, I can see in the messages as well that Davey sent the builder IO react hydration overlay.
00:10:33 So that's pretty cool thing to note.
00:10:36 We can also definitely share it in the discord.
00:10:38 So whenever you have anything, we have a forum and we can keep our discussion there.
00:10:42 It's quite useful to know that we can have better and improved error messages when it comes to hydration.
00:10:48 Thank you for sharing that.
00:10:51 But that's enough about SSR for now.
00:10:54 You get it.
00:10:55 Since we have this solid SSR approach, why should we bother with React server components?
00:11:02 Well, the conventional hydration we discussed earlier before React Server components in Next 13 involved a full page hydration.
00:11:11 This meant that when the page loaded, the entire React component 3, including all components, whether initially visible or interacted with by the user,
00:11:21 were hydrated on the client side.
00:11:25 What does this mean for performance?
00:11:28 Although you can see something on the page, it won't be interactive until the client loads everything related to that page,
00:11:36 specifically the necessary JavaScript bundle to hydrate the static tree.
00:11:41 Sure, we achieve a faster initial load at this stage, but then there's a delay we can interact with.
00:11:49 And because we're waiting for the JavaScript to hydrate, there's a gap.
00:11:54 For more extensive code bases, it can lead to larger initial page loads and processing of JavaScript, even for components that may not be initially required.
00:12:05 So here's where the React Server components step in.
00:12:12 React server component is a fresh component type.
00:12:16 It's assured to run exclusively on the server.
00:12:20 They never get hydrated on the client side.
00:12:23 So as a result, no extra JavaScript is sent resulting in a smaller JavaScript bundle size, faster page loading, selective hydration,
00:12:35 and an enhanced experience for both UI and developer experience.
00:12:42 But before that, let me explain how does React Server Component work and how we can use them.
00:12:49 It's important to note that React Server Components are exclusively a React feature.
00:12:59 There's been a lot of debate on the internet now.
00:13:01 Hey, why do we need Next.js if this is a React feature?
00:13:05 Not sure where you stand with that point, but It's pretty simple, right?
00:13:10 React server components are an exclusive React feature.
00:13:16 But it isn't tied to any specific framework.
00:13:19 Makes sense so far, right?
00:13:20 Although, currently, the recommended way to utilize React server components is through Next.js.
00:13:29 Here, you can see it mentioned right in the official React.js docs.
00:13:35 It's technically possible to use it independently.
00:13:37 Nevertheless, using it without a framework is not advisable for production and the setup can be a hassle with Pure React.
00:13:47 You can check out the demo right here.
00:13:51 Before we check out the demo, I want to ask you a couple of questions here.
00:13:55 What's your stance on that, kind of using React Server components independently of a framework?
00:14:00 Have you tried doing that before?
00:14:02 Have you tried to use it for larger code bases?
00:14:05 I know it's hard to break the ice, but I always like to have some interaction happening as well.
00:14:11 Feel free to use the chat as well, might be a bit easier.
00:14:14 Yeah, I see a couple of people just saying that they haven't used React Server components yet.
00:14:19 Yeah, they're quite new, right?
00:14:20 And React didn't really provide a simple way for us to use them.
00:14:24 But if I asked a question, right?
00:14:27 Have you used React Server components with Next?
00:14:31 The answer changes dramatically, I'm guessing, right?
00:14:33 So give me just a quick yes or no if you have used them with Next.
00:14:37 Yeah, I can see a lot of yeses right there.
00:14:40 So this is the official React Server components demo right here using just React.
00:14:47 So what you can see here is that we definitely can use it, right?
00:14:53 We have the server, but it needs a server, right?
00:14:56 So here we can see that inside of the server, API server.js, if we scroll down to the app.get right here, and I'm going to zoom it in just a tiny bit,
00:15:10 We have this app.get forward slash, and you can see that we're sending HTML back right here.
00:15:16 So this is technically react server components in action.
00:15:20 It's getting them from the server and it's returning them back.
00:15:22 We're now diving into the official code base.
00:15:26 Moreover, the React or Render React tree right here isn't just constructing the React tree as we discussed.
00:15:34 It's handling various tasks, including sending responses and creating routes for other pages as well.
00:15:41 So if we step outside of this folder and inspect the package.json file right here, you'll notice that we are utilizing React DOM server webpack right here,
00:15:55 this package.
00:15:58 18.3.0, next version right here.
00:16:00 And we're also using the server-only package, 0.0.1. That's a good one.
00:16:07 This is the process when using React server components without any framework at the moment.
00:16:11 It requires us setting up our own server, scripting, and handling rendering independently.
00:16:17 And this is where frameworks like Next.js become valuable.
00:16:21 Okay.
00:16:22 Using a React server component in Next.js is effortless.
00:16:27 In the latest version of Next.js, the app router makes the RSC the default component, as you all might know.
00:16:37 which is pretty exciting.
00:16:39 So now I want to dive into a quick demo.
00:16:42 Yep, we're going to have demos as well.
00:16:44 I haven't prepared any videos for that.
00:16:46 It's going to be just a quick, good old Visual Studio Code demo, which as you might know, often go wrong.
00:16:52 So bear with me.
00:16:54 You cannot have a demo without something going wrong, right?
00:16:58 What we're going to do here is we're going to ensure that we are on my desktop right here, or rather just create a new file right here for Git Nation.
00:17:08 All of these files will be provided to you in the Discord server later on, and we'll be able to have more conversations about that as well.
00:17:18 So we're going to start from really bare beginnings by creating a new terminal right here and creating a new Next.js app by running MPX create next app.
00:17:30 Let's choose a name.
00:17:32 In this case, we can do something like hello-rsc.
00:17:36 And I'm just going to press enter for everything.
00:17:39 We're going to get the default settings.
00:17:41 And this is going to create a new basic Next.js file structure.
00:17:46 Now there we have it.
00:17:48 We have our own application and the component, of course, is within the page.tsx.
00:17:54 This is our first React server component.
00:17:57 How do we know?
00:17:59 Can somebody let me know how do we know that this is a server component?
00:18:03 Yeah, that's correct.
00:18:04 Radek, I hope I got that right.
00:18:06 Simon as well.
00:18:07 There is no use client directive at the top.
00:18:10 That's it.
00:18:11 It's as simple as that.
00:18:12 We don't have to do anything else.
00:18:14 Next.js does it by default if we don't go out of our way to specifically provide the use client directive.
00:18:22 Great.
00:18:23 So now let's go for a quick demonstration right here.
00:18:27 If we add a console log right here, let's do it maybe right here at the top, console.log.
00:18:34 And if we do something like hello from RSC right here.
00:18:40 Let me, let me try to spell it correctly.
00:18:43 There we go.
00:18:44 Hello from RSC.
00:18:46 And now if we run our application by running MPMI, we first have to navigate right here.
00:18:53 So moving to Hello RSC, run MPMI, and then run MPM run dev.
00:18:59 If we run it, and if we visit our app on localhost 3000, There we go.
00:19:05 I believe we can see hello from RSC right here in our terminal.
00:19:10 And if you open up the inspect element right here, you'll be able to notice that there is absolutely nothing happening in our browser console.
00:19:19 Pretty simple, but we do see it right here in our terminal.
00:19:24 So if we inspect the view or view the page source of this application, we can do it right here and go to the HTML part as well in the elements.
00:19:34 There we go.
00:19:34 Bear with me.
00:19:36 Cool.
00:19:37 We can see our CSS, which we're not concerned with at the moment, but we can see the script tag right here.
00:19:43 The last script tag, I believe it is.
00:19:46 And we can see self next push right here.
00:19:50 And this script tag is going to display the actual content of the website, as you can see it here.
00:19:56 Name, viewport, content.
00:19:58 Why is a script returning HTML here, right?
00:20:01 Well, despite being a sizable code chunk, you can directly see the actual content here.
00:20:06 Before I explain that, let's go back to the application and I'll quickly show you something.
00:20:11 Let's navigate to the .next folder right here.
00:20:15 and I'm going to put this just on the side for now.
00:20:19 If it lets me drag and drop it, not yet.
00:20:22 I'm going to put it right here and we can go to the .next folder right here.
00:20:27 This is where the content rendered on the server will be visible.
00:20:31 Open the terminal and run npm run build.
00:20:34 I'm going to put it right here.
00:20:36 Feel free to replicate this later on in case you want to learn or just learn with me by running npm run build right here.
00:20:44 Now pay attention to what unfolds in the server folder.
00:20:48 That's a lot of stuff happening, right?
00:20:52 Now inside the server folder, there's a lot of files.
00:20:55 If you open the app folder in there, you'll find our generated HTML files.
00:21:00 So if we find the app here, you'll find all of the generated HTML files.
00:21:07 Formatting this just index.html will show you the exact code we had on our page.tsx, which was a pure server component.
00:21:16 Right underneath, there is something called index.rsc.
00:21:21 Yep, you can see it here.
00:21:22 It might not look very readable, but let's ask ChatGPT to simplify it and make it understandable for us.
00:21:30 If I do this, I can kind of open up a new window.
00:21:33 Let me just do that right here.
00:21:37 Oops, I think I lost it.
00:21:38 Let me do it on my other monitor and I'm going to bring it in.
00:21:43 This is another, I guess, point of topic right now and to discuss how often do you use ChatGPT in your daily workflows while I'm trying to get it open
00:21:52 and running, especially with development?
00:21:54 Or have you tried using GitHub Copilot?
00:21:57 Are you still staying on ChatGPT or using it literally never?
00:22:06 Okay.
00:22:06 I can see, yeah, I can see some, some people have said almost never.
00:22:09 And then I have most days, uh, copilot and chat GPT as well.
00:22:14 Um, that's good.
00:22:16 Yeah.
00:22:16 So if we do this right here, and if I try to just ask it to, to explain it for us, so, or at least say, make it readable,
00:22:26 let's see what's going to happen.
00:22:31 Okay.
00:22:32 Detailed structure, HTML and CSS elements.
00:22:36 Okay, to make it readable, break it down into components.
00:22:38 And now it's going to do its own thing.
00:22:39 I'm using GPT-4, so it's a bit slow.
00:22:43 Yeah, it's a bit slower, but it's going to go over the actual thing.
00:22:48 Should simplify it, I think, at the end of its discussion, kind of explaining what it is.
00:22:52 But you get the idea.
00:22:54 Essentially here, we should have a tree representing the page content, displaying all the elements from top to bottom.
00:23:00 So can you simplify it?
00:23:03 It can be a hit or miss, as you might know, right?
00:23:06 So it immediately knows that it's a Next.js page, and it just appears to be explaining it.
00:23:13 But I was wanting it to provide me a tree, but that's hard to see.
00:23:18 Essentially, what we should be getting if we try to dissect this, you're going to notice that we're going to have a tree of different elements,
00:23:25 right?
00:23:26 And try to remember that mental model created by Dan Abramov.
00:23:31 React server components don't directly produce HTML files.
00:23:36 Instead, they generate a virtual DOM structure like we see right here, and that's how React, the library, knows what to do.
00:23:46 So now what we can do is, I guess, just ask ourselves, when should we be using React Server components?
00:23:54 Let me see.
00:23:55 Give me one second.
00:23:57 If we go back to our demo right here, There we go.
00:24:01 We have this huge thing right here.
00:24:03 And currently, we're not utilizing any client component.
00:24:08 I guess the question is, why would we use any client components whatsoever if we can use server components?
00:24:13 Well, let's try to create a small client component inside of the app folder to just try to compare the differences between how they're being rendered in
00:24:22 the background.
00:24:23 So if I go here to the app, let's create a new component.
00:24:28 I guess we can call it client.tsx and we can run RAFCE just to get it going really quickly.
00:24:37 And we have our client component inside of which we can use the use client directive.
00:24:42 There we go.
00:24:44 This is pretty simple.
00:24:46 What I would want to do as well is create another sub component, const sub client component as well, which is going to look like this.
00:24:55 This sub client component can just return a div that's going to say sub client component.
00:25:02 Now we want to modify the page.tsx file to write something basic, which is going to allow us to get the minimal RSC.
00:25:10 So if we go back to the page, I'm going to just replace this entire main.
00:25:15 And where I want to get to is just return a main.
00:25:19 It's going to say something like, welcome to git nation.
00:25:25 There we go.
00:25:26 And we can add a p tag right below.
00:25:30 That's going to say something like this is a server component.
00:25:34 Okay.
00:25:35 We're doing it step by step.
00:25:36 Now let's see what we get without importing this client component inside of our main page.tsx.
00:25:45 Let me see.
00:25:46 If we try to run npm run build one more time.
00:25:53 Okay.
00:25:53 As you can see, it's building it.
00:25:54 It's taking a bit more time now.
00:25:57 And within our dot next, we have server, we have app, we have the page dot JSX.
00:26:03 Once again, we have static too.
00:26:05 There's a lot of stuff happening.
00:26:06 And then we have the pages or four and 500 getting generated automatically.
00:26:11 Um, let me just see what I was after specifically here.
00:26:18 If we go.
00:26:21 Oh yeah, there we go.
00:26:22 I can see the chat GPT response provided, and this is exactly what we were after.
00:26:27 So if I bring it right here, this is kind of what we were looking for, right?
00:26:32 So we have the entire version, simplified version of the code where we have the code chunk one, code chunk two, code chunk three,
00:26:40 code chunk four, which is huge and contains all the children right here with class names and everything.
00:26:46 This is what a React Server component is.
00:26:50 It is a straightforward restructuring to enhance readability in this case.
00:26:54 So that's how React server components work behind the scenes to generate and send that data over to our dynamic virtual DOM.
00:27:07 And also in there, there is never the code for the client component.
00:27:10 The only thing that it has is the code for the server components.
00:27:15 Now, this was a quick demo, but I want to dive into answering the question of when should we use React Server components in the first place.
00:27:26 There we go.
00:27:28 Next.js documentation explains it really clearly.
00:27:31 It truly is one of the best documentations in the world, where it shows us that exactly when, and it's giving really simple kind of solutions right here.
00:27:42 Here we can see that when I'm developing my app, I ask myself, does this component require interactivity?
00:27:49 If the answer is yes, right?
00:27:51 Let's kind of sketch this out a bit.
00:27:53 If the answer is yes, it's a client component.
00:27:55 If the answer is no, it's a server component.
00:27:58 And this follows the principle of separation of concerns.
00:28:03 guiding us to create server components and client components based on their specific roles.
00:28:08 So let's see why should we use React server components.
00:28:13 First of all, they're going to result in a reduced client side code where the proper use of RSC allows us to keep most code and necessary changes on the
00:28:24 server side, minimizing or eliminating the bundle size for RSC component to be sent to the server side.
00:28:31 Okay?
00:28:33 Reduce client-side code means faster load times and many more benefits.
00:28:38 Enhance security, right?
00:28:40 Because fetching data on the server side is more secure than on the client side, where environmental variables are easily exposed.
00:28:48 And we know this, right?
00:28:49 But sometimes you can fall into a trap of accidentally doing it there.
00:28:53 And this way, it's always in the server.
00:28:56 Improved latency as well, where the server-side execution of fetch or database operations result in better latency, as servers and data centers are typically
00:29:07 geographically close, leading to faster responses and faster access to the data.
00:29:14 And finally, we have UX and DX benefits.
00:29:18 React server components just have a better experience than traditional SSR, a topic which we'll dive into shortly.
00:29:27 On the developer experience side, using RSC, especially for data fetching, is straightforward.
00:29:33 In earlier versions of Next.js, data fetching on the server side was limited to the page level.
00:29:41 It wasn't possible to do server-side data fetching on the component level.
00:29:45 Now it is.
00:29:48 Also, the process was a bit less intuitive, contrasting with the simplicity of using React server components.
00:29:57 As you can see, this is a big chunk of code where we have something simple, seemingly, right?
00:30:02 But then we have to do this entire get server-side props thing as well.
00:30:07 I'm guessing most of you are aware of that, where now we have something that is much simpler.
00:30:16 We have exactly what we want, a typical React component where we have search parameters at the top, giving us access to the data we need.
00:30:26 Similarly to what we've seen before, but in a much more simplified code base and much simpler understanding.
00:30:35 That's what developer experience is all about, right?
00:30:38 We can build great things and ship them in weekends, right?
00:30:42 We've seen a lot of people just done a lot of great projects in short amounts of time because Next.js allows you to do all of these things right out of
00:30:51 the box.
00:30:53 So let's do a quick summary so far.
00:30:56 React server components are components that specifically run on the server side.
00:31:02 They produce an RSC payload, which is essentially a server-side representation of the entire virtual DOM, the document object model,
00:31:11 for a given application.
00:31:13 This payload outlines where each component should be placed in the DOM structure.
00:31:19 and frameworks like Next.js coming to play at this point.
00:31:23 They take the RSC payload and the HTML file generated from the server side, virtual DOM, and send them as a package to the client,
00:31:34 which is the user browser.
00:31:36 Now, on the client side, the browser reads the server-side virtual DOM and starts constructing its own version.
00:31:43 It adds necessary client-side components to the tree as specified, and this process is called hydration.
00:31:52 It's important to note that React server components and server-side rendering, SSR, are different concepts.
00:32:00 While you can use RSC on its own, doing so requires manual management of various aspects.
00:32:09 Whereas integrated frameworks like Next.js simplify this process by efficiently handling both RSC and SSR for you.
00:32:17 The SSR mechanism renders both the server-side components using the JSON payload or RSC payload generated by RSC and the client-side components,
00:32:28 ultimately transforming them into the HTML code that represents the blueprint of the entire application.
00:32:37 we should consider using RSC for data fetching.
00:32:41 Anything security related or sensitive information and heavy dependency execution.
00:32:46 Whereas RSC components, or sorry, RCC client side components, we can use for anything that needs interactivity.
00:32:57 And that's more or less it.
00:32:58 I was moving to the next slide expecting more things to come up, but no, right?
00:33:02 We only use RCC when it needs some client side interactivity.
00:33:07 It is as simple as that.
00:33:10 Now.
00:33:12 What this all means, if we properly use their corresponding components for what we need, it means that we're going to reduce client side code.
00:33:22 We're going to also improve security.
00:33:24 We're going to improve the network latency.
00:33:26 We're going to get optimized SEO and have a better user experience and developer experience, which is what matters to us the most.
00:33:35 Great.
00:33:37 Now, I will cover the edge versus node bit in the end, as we're deeply into the SSR and RSC mechanisms right now, which is the foundation for these bits.
00:33:48 But we learned that with client-side rendering, right here, we load everything and execute everything to show anything that looks like this.
00:33:58 Everything is happening on the client side.
00:34:00 Thus, our users had to stare at the white screen for a good amount of time.
00:34:06 With server-side rendering on the other end, we execute something on the server, like this, and then show something on the site and then load everything
00:34:15 to hydrate the parts that make the interaction.
00:34:19 Much better, right?
00:34:20 That sure improves the initial load times as we're showing something, a non-interactive thing at the start, but hey, they get something,
00:34:29 right?
00:34:30 So this helps us to not lose a potential not-so-patient users or customers, right?
00:34:38 And that helps us keep them.
00:34:41 I can see some comments right here, improve security, how?
00:34:44 Well, it's typically always better to run secure code on the server, as on the client side, things are easily exposed, right?
00:34:54 I'm not saying that this is improving the security over the typical server-side approach.
00:34:58 I'm just saying that maybe it makes it a bit easier for us not to make a mistake of exposing some variables on the client side.
00:35:08 Whenever you're doing some security stuff, whenever we're doing some payments, typically libraries and packages like Stripe don't even allow you to do
00:35:16 a lot of sites on the client.
00:35:17 So now it just makes it a bit more convenient to call it on the server.
00:35:22 And server being the components directly, right?
00:35:24 Which makes it super easy to do so.
00:35:27 Now, to address some of the mentioned issues, React 18 introduced two significant concepts, streaming and selective hydration.
00:35:39 Streaming is like sending parts of a puzzle from the server to your computer as soon as they're created, instead of waiting for the whole puzzle to be
00:35:50 finished before sending it.
00:35:52 That way, the server delivers pieces as it makes them.
00:35:56 Whereas in traditional server-side rendering, when a user makes a request, the server starts creating the HTML page, and the client has to wait for the
00:36:05 entire page to be generated.
00:36:07 After receiving the page, which is just the initial content, the client then downloads all the JavaScript and begins hydrating it.
00:36:17 However, with streaming server-side rendering, as soon as the user makes a request, the server starts executing the components.
00:36:26 The moment they're ready, they're streamed down to the client one by one, and this eliminates the wait time for the complete page generation before content
00:36:35 is sent to the client.
00:36:38 But what if there's a network issue?
00:36:41 Well, think of it like a busy road.
00:36:44 Network, right?
00:36:45 And trucks being the data that can't move fast.
00:36:48 With streaming, if the road is full, the server pauses sending pieces of our data until there is space again.
00:36:56 This prevents the server from getting overwhelmed, and your computer can continue working on the puzzle when there's room.
00:37:04 And streaming enables your server to handle multiple tasks simultaneously.
00:37:10 Even when faced with challenges, your website remains quick and responsive.
00:37:15 So once again, this is a feature introduced in React 18. And to use it, you'll have to use the render to node stream to stream your app content.
00:37:28 As mentioned before, frameworks like Next.js thankfully have built in support for this.
00:37:35 All I need to do is grasp the concept, make informed decisions and focus on the business logic.
00:37:42 In essence, streaming server-side rendering utilizes render to node stream instead of render to string used in regular server-side rendering to stream
00:37:54 or send chunks of data as needed rather than sending everything at once.
00:38:01 Okay.
00:38:02 So server issues are not going to do anything to stop it.
00:38:06 And also, once again, we see that Next.js uses really conveniently and in a smart way, features that are built into React.
00:38:14 It just uses them and just kind of wraps them in a way that makes them easier for us to use.
00:38:19 But still, don't forget, we have to grasp the concept to be able to make informed decisions.
00:38:27 So what's selective hydration in the first place?
00:38:31 What do you think the hydration mechanism would be if we used streaming server side rendering where we're sending content as they're ready?
00:38:41 Well, wait for everything and then start hydrating?
00:38:45 That wouldn't be the best use of SSR, would it?
00:38:48 Well, with traditional hydration, we get the entire tree and then React hydrates it.
00:38:54 Start to finish only once.
00:38:57 Well, now imagine a child having a bunch of toys to play with.
00:39:03 Before that child can start playing with any toy, he needs to collect all the instruction manuals for the toys.
00:39:10 Of course, it's not really like this, but just bear with me for a second.
00:39:14 Now, if some manuals are really big, right?
00:39:18 He'll have to wait until he gets them before he can start playing with any toy.
00:39:23 Well, even if there are smaller toys with smaller manuals, he still have to wait for big ones to finish.
00:39:29 So until he has all the instructions, he can play with any toy.
00:39:35 This happens with regular hydration as well.
00:39:39 But with React 18 and Streaming SSR, React hydrates the tree without waiting for larger components to be ready.
00:39:49 That's what selective hydration is all about.
00:39:52 A process where React hydrates the components or chunks it has received via streaming rather than waiting for everything to be finished.
00:40:01 It starts hydrating as soon as it has something to hydrate.
00:40:07 But how will React know?
00:40:11 Well, it's simple.
00:40:12 Wrap whatever you think will take a longer time to load with suspense.
00:40:17 This tells React not to wait for this component to finish and to continue streaming and hydrating the rest of the content.
00:40:26 So does the virtual DOM or tree on the server get generated again?
00:40:31 What's the workflow here?
00:40:33 Well, the process goes like this.
00:40:35 We have to wrap the components that you think will take longer time to render, like this.
00:40:45 We can also then do some extensive calculations or operations and we just wrap that with suspense and we render the fallback that's loading.
00:40:55 That looks like this.
00:40:57 The client makes a request to the server.
00:41:00 React starts rendering the React server component and building the virtual DOM on the server.
00:41:05 And the moment it encounters the code where we're using the suspense, it'll use the fallback code inside of that tree.
00:41:12 And then continue building the rest of the part.
00:41:15 And now when the component is done doing its work, it'll stream new HTML containing the fallback code of suspense to the client,
00:41:22 along with sending the script to show what has been replaced with the fallback code that has been rendered on the UI.
00:41:32 It's not so easy to grasp, but the underlying mechanism is, of course, hard.
00:41:40 To demonstrate the workflow real quick, let's open up the application I have over here.
00:41:45 By the way, you'll get the complete GitHub code link in the description, or in this case, it's going to be in that Discord forum that we have.
00:41:53 I would really like us to continue the conversation going on there because we're discussing many topics that...
00:42:02 You cannot really find a lot of information for online.
00:42:05 And I think that's the point of going to conferences like It Nation, right?
00:42:11 Why are you here in the first place?
00:42:13 With topics new such as this one, maybe your employers have sent you or maybe you have come on your own, which is amazing,
00:42:19 to learn about how to use the latest and greatest of what makes us more efficient.
00:42:26 And nowadays, you cannot find that so easily online.
00:42:31 I know because I had to dig through a lot of GitHub pages.
00:42:36 There's no documentation whatsoever.
00:42:38 You have to find it on your own.
00:42:39 So the fact that you're here right now listening to this is just amazing.
00:42:44 Just wanted to put that out there.
00:42:46 So the link is going to be there and what I was saying is I would want us to continue this conversation on Discord because we can all learn from each other
00:42:55 even after this talk is done.
00:42:58 Great.
00:42:59 So let's kind of go over this app really quick and we're going to create a sample app, sample component wrapped inside of Suspense.
00:43:09 It's going to do fetch calls.
00:43:11 It's going to do a lot of stuff.
00:43:12 So let's dive into our second example of the day.
00:43:17 I'm going to close this, collapse all the files and just re-navigate back over right here.
00:43:25 We're going to create our second example of the day by running MPX, create next app, and we're going to call it, let's do something like hello-stream as
00:43:36 we're learning about streaming.
00:43:48 Excuse me, Adrian.
00:43:50 Yeah, sorry, go ahead.
00:43:51 I am tempted to follow along as you code this, but I'm not sure if that was the intention.
00:44:00 Yeah, I think it will be tough.
00:44:02 But I would say we're going to have a recording of this.
00:44:05 We're going to also have a a Discord chat, and I'm also going to give you full examples of these repositories that we're creating.
00:44:14 So I would recommend maybe watching along, keeping some notes, which would be great as well.
00:44:19 And then we can later on revisit them and you can ask questions if you have any, while you try to replicate that later on.
00:44:27 Is that okay?
00:44:28 Yeah.
00:44:29 Thank you for clarifying that.
00:44:30 That's great.
00:44:31 No worries, Vanessa.
00:44:33 Yeah, let's also see.
00:44:35 I have, let's see.
00:44:36 So let's try to open up this stream and what we can do is go into here.
00:44:44 Give me one second.
00:44:45 Just trying to ensure that we kind of explain this as good as we can.
00:44:51 We have this hello stream and I want to ask for a second.
00:44:54 I have my colleague here preparing also some files for me here.
00:44:59 I'm trying to figure out what exactly we should show here.
00:45:02 We also want to get to this tree that we talked about not that long ago.
00:45:07 So let me just create a demo.js file right here.
00:45:11 And essentially, we're talking about this tree doing the loading.
00:45:15 So we want to figure out where we have this React suspense.
00:45:20 But of course, I want to figure out a way to get to that.
00:45:23 So instead of me writing the entire piece of code here, let me just open up, or rather paste a new folder right here, which is going to be called HelloStream,
00:45:32 but rather the new one containing the code.
00:45:35 So here, we want to go ahead and proceed with the demo.
00:45:39 Um, as you can see, it's once again, a simple page where we just import a component called dot slash sample suspense.
00:45:46 We're still rendering the component on the, on the, on the server side right here.
00:45:53 And we have the main right here where we have just rendered the main H1 HTML.
00:45:59 We have a server component and then we're calling the suspense right here.
00:46:03 With a fallback of a simple loading and then putting the sample suspense right here, which is calling our Pokey API.
00:46:11 So it's doing an API call still on the server.
00:46:14 It's getting us some data and then it's showing that data in a JSON stringified way.
00:46:21 Okay.
00:46:22 Pretty simple example.
00:46:25 So now what we can do is I'm going to navigate over to the hello stream.
00:46:30 Let's go to hello stream copy.
00:46:33 I believe if it's going to let me do that, uh, let me just, uh, rename it to hello stream one bear with me here.
00:46:43 There we go.
00:46:44 I'm going to navigate over to hello stream one, and I'm going to run NPM install.
00:46:54 And then I'm going to run it.
00:46:57 And then we should be able to see a new folder appear right here, which is going to be dot next.
00:47:02 There we go.
00:47:04 And now if we go into, I believe it's here, right?
00:47:11 Server.
00:47:15 And then we have the app folder right here.
00:47:17 Let me see.
00:47:19 I think I have to run the build right here.
00:47:23 Yeah, so let me run the npm run build so we'll be able to actually see it in an example here.
00:47:33 Yeah, there we go.
00:47:34 And yeah, I also can see you're asking for the link of the repo.
00:47:37 Yes, we're going to share a link.
00:47:39 I believe it's public already.
00:47:40 So my colleague will just pass it into the chat and we're going to also have the full video as well as the repo and everything else on the Discord forum
00:47:49 later on.
00:47:50 I believe it's going to be the best way to keep the communication.
00:47:53 I believe somebody from Git Nation, Alexander maybe has already shared the forum at the top.
00:47:58 Yeah, I believe it's there.
00:48:01 Um, so now we have this, um, server and we have the app in the server because now we have built it.
00:48:07 And then here, what we're looking for is we have the page.js.
00:48:16 Once again, it's quite hard to read, but if we search for.
00:48:22 Suspense you can see is being used a couple of times and we can see the code being generated right here.
00:48:28 So it's rendering the children of loading.
00:48:30 And then the second time it's going to render once it's finished doing its work, it's going to give us back the data, uh,
00:48:37 from pokey API.
00:48:38 That's kind of the idea of this.
00:48:39 There we go.
00:48:40 So once again, we can see a wait patch.
00:48:44 Um, Yeah, I would like to show you the tree that's being generated.
00:48:54 I would just have to find where it's generating that tree.
00:48:58 Let me see.
00:49:02 Yeah, so it's in the index RSC.
00:49:04 And there we go.
00:49:04 This is the tree right here that we can see where we have the two React Suspense.
00:49:11 And in the React Suspense, we can see a couple of things.
00:49:15 We can see the number two, which is the just React Suspense.
00:49:19 We can see the fallback right here, which is rendering the children of loading, right?
00:49:26 It has an L3 reference right here.
00:49:31 And then we can see another children right here.
00:49:36 It's been mentioned a lot of times, but we have the second one where it's actually rendering the actual content that's coming back.
00:49:46 There we go.
00:49:47 It's right here.
00:49:48 It's quite easy to notice it because this time, once it renders it, we get the response from the API back with the count of 64 and all the results right here.
00:49:57 So this is how React suspense work.
00:50:00 It's being sent as a script right back within index.rsc.
00:50:08 And now we can run the run dev, go to localhost 3000. And we should be able to see how that actually works.
00:50:17 There we go.
00:50:18 We have welcome to Git Nation.
00:50:20 This is a server component.
00:50:21 And then we can see sample suspense component right here.
00:50:25 If I reload.
00:50:26 Maybe we'll be able to catch it.
00:50:28 Nope.
00:50:28 I think it caches it.
00:50:29 Once again, we're going to talk about cache a lot later on, but now it's always going to be here and we can see the entire thing.
00:50:36 And it's going to be similar.
00:50:37 If we inspect it and go to elements, you can see that it's being provided to us right here in this script where it pushes it later on.
00:50:45 So we have script.push, sample, suspense component.
00:50:51 And yeah, the code is being just provided to us here.
00:50:54 It pushes it whenever it gets it.
00:50:55 That's the idea of streaming, right?
00:50:58 Let's see.
00:51:01 So at the start, we see the loading.
00:51:04 Then later on, we see index HTML.
00:51:06 And that's exactly how the process is.
00:51:09 Let me just go back from this example.
00:51:11 And once again, all of these examples will be provided to you with the code, as well as within the chat and future information,
00:51:18 maybe in the readme of each one of these examples.
00:51:21 So we'll be able to dive into them and I'll keep building on these examples as well.
00:51:27 We have a question as well.
00:51:28 So basically React suspenses some content and shows ready placeholders instead of them by the time the background trying to make them ready and when they're ready,
00:51:37 React just replaces them.
00:51:39 That's entirely, that's exactly right, Halil.
00:51:42 That's phenomenal.
00:51:44 It's called streaming.
00:51:46 You nailed the concept of streaming perfectly.
00:51:50 We stream that content on the server to the client, React renders it, replaces it, and it's like nothing else has ever happened.
00:51:57 It just works seamlessly.
00:51:59 So that's our streaming SSR, the advanced version of SSR concept.
00:52:05 Quite new, not a lot of people know about it yet, so it's pretty cool that you're here listening to it.
00:52:10 Now, there are two main types of SSR, regular and streaming.
00:52:17 We just learned about that, right?
00:52:18 Within Next.js, these types further break down into Of course, why would it have to be two if it can be more?
00:52:27 Static rendering, which happens during build time of an application, where pages are server rendered at build time, and it's like what we have been doing
00:52:37 so far when running npm run build.
00:52:40 So far, static rendering, also known as static site generation.
00:52:46 It's the default strategy used in Next.js.
00:52:50 Now for dynamic rendering, this renders the application for each user at the time of their request.
00:52:57 So whenever a user makes a request, the page is generated and sent to the client.
00:53:04 Dynamic.
00:53:05 Every time.
00:53:07 A remarkable piece of feature innovation is that you can decide what should be static or dynamic rendered on page layout on a route level in Latest Next.js.
00:53:20 Doing that is super simple.
00:53:22 As you can see, all we have to do is add this sort of flag in the page or route, and Next.js will automatically show something differently.
00:53:33 So there is this flag.
00:53:35 Route segment config is just a matter of providing the right config right here.
00:53:43 Specifically, we can talk about cache.
00:53:45 I know there's been some backlash for Next.js for not allowing us to properly specify what we want to do.
00:53:52 Do we want to cache?
00:53:52 Do we not want to cache?
00:53:54 I think they're continuously adding new ways for us to modify the way that our content actually renders.
00:54:02 You can choose whether it's static, force static, force dynamic, auto, pretty cool thing.
00:54:10 Specifically in this case, we're talking about revalidate, right?
00:54:13 So you can force cache it.
00:54:15 You can just leave it as zero or a number in this case, but yeah, you can decide force cache if you don't want your content to update,
00:54:24 but you can leave it as false if you want it to revalidate for different users.
00:54:30 Additionally, you can also choose the middle ground, which is keeping the static content for a while and then changing it afterward.
00:54:40 This is known as incremental static generation.
00:54:44 Initially, all pages are statically rendered during build time.
00:54:49 After a set timer, which we can customize, the server renders the pages again and serves them to the client via a CDN.
00:55:00 You can specify and opt for this feature using the revalidate of Next.js.
00:55:06 Okay, so we can just provide a simple variable of export cons revalidate at the top of a specific route, and you can set it as a number.
00:55:14 I believe it is in seconds.
00:55:16 So if you set something like 1,200, it's going to revalidate every 20 minutes.
00:55:22 It depends on how dynamic you want your app to be.
00:55:26 and how fast, right?
00:55:27 If it's cached and if you don't need it to change, it's phenomenal.
00:55:30 It renders in an instant.
00:55:32 If you need to fetch new data every minute or every 20 minutes, you can specify exactly that.
00:55:40 Moving on, do you remember how we did data fetching in React server components?
00:55:46 It was this.
00:55:48 You simply specify it, you make the function async, and then you fetch some data, get it, and present it.
00:55:55 That's it.
00:55:56 Now, what if there are two or more requests that we have to do?
00:56:02 For example, first, check if a user is authenticated and then do the data call to get further information.
00:56:11 A solution to this is what we call, if another word right here, sequential data fetching.
00:56:17 A situation where requests in a route or a page are dependent on each other.
00:56:24 That's going to look like this.
00:56:28 Imagine you have a series of tasks you want to complete, like building a tower of blocks.
00:56:36 Sequential data fetching is like doing one task at a time, where each task depends on the completion of the previous one.
00:56:44 It's like adding one block and then waiting for it to settle before doing the next.
00:56:51 You might want to compare this with doing promises, right?
00:56:54 When you do dot then, dot then, which is just one after another.
00:56:58 And we also have promise that all, which does all of them at once.
00:57:02 I would say chaining the promises one after another is similar to sequential rendering.
00:57:08 So sometimes this order is essential for cases like we discussed above.
00:57:14 However, if we're not careful, you might unintentionally create a situation where you have to wait a long time before starting the next task.
00:57:23 So while sequential fetching can be useful for a few specific conditions, it can unintentionally make things take longer to finish.
00:57:35 And this phenomenon in tech terms is also known as a waterfall.
00:57:40 So how not to create request waterfalls?
00:57:44 Well, there might be a case in which we want to make multiple requests that are not dependent on each other.
00:57:52 How can we handle such a case without blocking the application?
00:57:56 Well, that's where parallel data fetching comes into play.
00:58:01 As the name suggests, it allows us to call multiple requests in parallel.
00:58:07 Think of parallel data fetching like having multiple helpers to get things done at the same time.
00:58:13 Instead of doing one task after another, all the tasks kick off together.
00:58:18 It's like having several friends who work on different parts of the project at the same time.
00:58:24 Although might not be the best example, as we might know that the more developers you add to the project, it might end up taking longer.
00:58:32 But let's kind of not think about it this way now.
00:58:36 So how can we do that?
00:58:38 It's, I would say, simple.
00:58:41 Yes, there are many things that we can do in XJS, and that's why many people like it.
00:58:46 Check this out.
00:58:48 What we have here is an async function where we have sample parallel fetching, where we get the params, and then based off of the params,
00:58:56 which are still server-side, we fetch a specific product by running the product.findById function and passing the params ID.
00:59:04 Only once we get the product, can we find the reviews for that product.
00:59:10 We could technically hold the two things at the same time.
00:59:15 You don't have to wait for the product to be able to fetch the product reviews because you only need the ID to be able to fetch the product reviews.
00:59:25 So what do we do here?
00:59:27 We chain it in a product reviews and we get the await promise all.
00:59:31 See, similar thing that I've been telling you about is how you might have been imagining it this entire time.
00:59:37 You just put it in a promise all where you get product and the reviews, but it's so cool how they have done it.
00:59:43 You pass an array of two different calls.
00:59:48 Would you say this is more so JavaScript than Next.js?
00:59:52 I guess that's a good question, right?
00:59:54 Because we have all been used to Promise Alls and I loved when it came out that it's so convenient to be able to use it right here within our Next.js application now.
01:00:05 So now we start showing both once the Promise All finishes.
01:00:10 So we await the product and the reviews and we show both once we get the data for it.
01:00:17 Okay?
01:00:18 Now, there's another thing I want to talk about really quickly, and it's called preloading data.
01:00:25 It's another way to prevent waterfalls is to use the preload pattern.
01:00:29 You can optionally create a preload function to further optimize parallel data fetching.
01:00:34 And with this approach, you don't have to pass promises down as props.
01:00:39 The preload function can have any name as it's a pattern, not an API.
01:00:46 That's going to look something like this.
01:00:48 We have a function export cons preload that gets the ID and it simply gets a specific item.
01:00:56 And then we can call it right here.
01:00:57 Cons result is equal to a weight get item and it's going to get preloaded.
01:01:03 I would definitely want some more information on this, but as you can see, and as I repeat myself, this is it.
01:01:11 The preloading data documentation page doesn't have too much info.
01:01:14 It's growing and we're at the bleeding edge right now, not only of Next.js, but also of React.
01:01:21 So sometimes we'll need additional examples from the creators of these features, digging deep into their GitHub pages, into their examples,
01:01:29 code bases, and more to be able to learn it.
01:01:32 or we can keep discussing it as well in our Discord forum.
01:01:37 So this was a lot of things to cover.
01:01:41 We are trying to understand what React server component workflows are, client-side rendering, SSR, streaming SSR, different types of patterns and when
01:01:53 to use what and all that.
01:01:55 Now, you might have a question.
01:01:57 If we do direct fetch or DB calls right here inside of the React server components, and would you want to have that same information in a subcomponent,
01:02:08 then what would that way be?
01:02:10 So this component makes a call to the server, and how do we get the data here?
01:02:14 In short, a question, where would you like to share the same data across multiple platforms?
01:02:22 Um, for a few components without turning everything into a client side or leveraging the same features we talked about.
01:02:29 The question of course, is it possible?
01:02:32 The answer is yes.
01:02:33 And how you're going to hear me say that again, it's simple.
01:02:37 We have to make fetch DB calls again, wherever you want.
01:02:42 But of course, wouldn't that mean too many fetch DB calls?
01:02:47 Well, not if we're being careful of what we're doing.
01:02:51 And this welcomes us to another topic of today, where we talk about cache, right?
01:02:59 Typically, in the previous world of React or just JavaScript or some other programming languages, technologies, this would be so bad,
01:03:06 making the same request to get the same piece of data from two different places.
01:03:10 Double the API calls, double the network payload data, double the everything, right?
01:03:16 But thankfully Next.js abstracts yet another thing in this whole journey of abstracting things and making things better.
01:03:23 And it does it through cash.
01:03:27 Before diving into cache, I want to make kind of a segue here and I would want to get a bit of a pause to let us all read for a second.
01:03:36 We covered an exceptional amount of data and information in this, I'm not sure how much time has passed, about an hour, right?
01:03:45 Maybe even an unhuman amount of data that we definitely cannot process in an hour.
01:03:51 So if you're going to get one thing from this workshop, I would want you to get just the idea of all of this.
01:04:00 Just know that it exists.
01:04:03 Just know that maybe when you're developing an application in the future, remember that you've heard about this.
01:04:09 Remember that it exists and remember that Next.js most likely abstracts it in a way that makes it easy for you to consume and to actually put into your application.
01:04:20 So don't try to kind of be bummed about not understanding or not properly even hearing all the things that I shared right now.
01:04:31 It's impossible.
01:04:32 So just be cool about that.
01:04:35 Know that you're going to have all of these examples, demos, and everything we shared in a link.
01:04:41 We shared it already in the chat.
01:04:42 We're going to share it multiple times.
01:04:44 We're going to keep building on those examples.
01:04:46 and take it slow.
01:04:49 Just know that these concepts exist and then just utilize them when you need them by going to the documentation.
01:04:56 I just want you to introduce you to these concepts, not to teach them to you right now, right off the bat.
01:05:05 It's impossible, especially on larger applications.
01:05:10 So let's take a bit of a pause right here.
01:05:13 Feel free to kind of discuss it in the chat most likely.
01:05:17 And then we can take maybe a 10 minute break and then we can come back and talk about even more new cool features continuing with cache.
01:05:27 Okay.
01:05:27 Yeah.
01:05:27 As I said, I try to throw in as many of these concepts as possible.
01:05:32 My team and I have spent a lot of time digging into these features in the alpha and then beta and then now stable with server actions with cache.
01:05:41 It's tough, right?
01:05:42 But again, the more you know about it, I don't want to give you some definite answers right now.
01:05:50 I want to introduce you to topics and then you will be able to dig into the docs, but I want you to just know that these things exist.
01:05:58 So let's take a bit of a break and then we're going to dive deeper into all of this.
01:06:03 Okay, that's great, that's great.
01:06:06 Yeah, coming back to cash right here.
01:06:09 Cash is a topic that some people didn't really like how Next.js handled.
01:06:18 Are you maybe one of those?
01:06:22 Because Next.js seemingly too much abstracted the way for us to handle cash.
01:06:31 Some people say that they would prefer a bit more ability to manage what, when, and how does it get cached.
01:06:40 Okay, so now we're going to start right off with demo and I'll give my best to show you that Next.js gives you a lot of possibility to modify the way that
01:06:54 things get cached.
01:06:55 Maybe even too much.
01:06:56 No, just the right amount, right?
01:06:59 But not too many people know about how to modify it all.
01:07:02 Maybe it should have been more obvious in the docs, but we're going to go through it together.
01:07:08 So let's start with the next example right here.
01:07:10 I'm going to just get the hello cache folder right here, which we can together explore.
01:07:17 So I'm just going to paste it right here.
01:07:19 And it's once again, going to be a typical Next.js application.
01:07:23 And we want to ensure, but let's first look into what we have here.
01:07:29 Well, I'm going to run, I'm going to navigate to it, navigate to Hello Cache.
01:07:35 CD Hello Cache.
01:07:37 There we go.
01:07:38 And run MPM install first so we can nicely see it.
01:07:43 And I'm going to later on run it and I'm going to show you a little cool trick that you can do as well.
01:07:48 So first of all, right here within this hello cache, let's talk about what this is even doing.
01:07:55 Here we have a homepage where we fetch once again, some data from the Pokey API.
01:08:01 We return it and we stringify it and display it.
01:08:04 Pretty simple.
01:08:06 In the layout, nothing too interesting is happening.
01:08:10 And we have another fetch right here, which is a component, which is doing the same exact fetch.
01:08:17 We can show it right here.
01:08:19 It is the same exact thing happening right here.
01:08:24 Limit 10 version two Pokemon, just give us the data and display it.
01:08:28 But here you can see same fetch and then it's returning it.
01:08:33 But right now we're not using this component whatsoever.
01:08:36 It's just being imported right here.
01:08:38 Now, what we want to do is we want to enable some loading right here.
01:08:45 I want to enable additional logging options by Next.js.
01:08:49 And there's a nice documentation page that looks like this.
01:08:52 Again, something that not a lot of people know about.
01:08:55 It allows you to configure the logging level and whether the full URL is locked to the console when running Next.js in development mode.
01:09:03 So what we can do is we can enable this full URL mode in NextConfig.js by doing this logging part right here.
01:09:11 So if we go back and go to NextConfig right here, you can see that we have enabled logging full URL.
01:09:18 So what I'm going to do right now is I'm going to run NPM run dev to get our application running.
01:09:23 And on localhost, we can see something that looks like this.
01:09:29 It's going to be just all the data that we get back from the Pokey API.
01:09:33 And we get it right here, 202,620 milliseconds.
01:09:39 We get the request right here.
01:09:41 And you can see the cache hits a skip right here, which is interesting.
01:09:45 First of all, you never usually see this.
01:09:47 You're only seeing this right now because we have enabled logging.
01:09:51 And now what we want to do is delete the next folder and then restart it again.
01:09:58 Okay, we're going to try to see which routes have different things right here.
01:10:03 And give me just a moment.
01:10:05 So this demo is just phenomenal.
01:10:07 We have a lot of things going on.
01:10:09 And as I said, we're at the bleeding edge right now of just caching in the way that Next.js handles it.
01:10:16 I'm going to be right now completely honest.
01:10:19 This demo was created for me by my colleague Sujata.
01:10:24 She's here as well with us.
01:10:26 So if I get stuck trying to explain some of these parts to you, she'll be able to just jump in and help us as well.
01:10:33 Essentially, we have this About page right here, where we're doing the same exact thing as we're doing in the homepage.
01:10:40 Two of the same exact pages.
01:10:43 And we're doing, once again, the same exact call.
01:10:47 So now, what we want to do is maybe also navigate to that page to see what's happening.
01:10:52 We can do that really quickly by going to the About.
01:10:56 So let me just open it.
01:10:57 I think I have it open already.
01:10:59 Should be right here.
01:11:02 There we go, localhost 3000, and we can see it right here.
01:11:05 And we can also navigate to forward slash about.
01:11:09 Same exact thing, right?
01:11:11 But what happened right here?
01:11:13 You can see that we get cache hit, which means that it found the existing cache and then it hit it.
01:11:19 Okay.
01:11:21 Same thing.
01:11:22 And we have skipped one more time because it also skipped it.
01:11:26 So Sujata, which is my colleague right here, I want to ask you, would you mind kind of diving deeper into the way that we hit or skip specific elements?
01:11:34 Yeah, for sure.
01:11:36 Hello everyone.
01:11:37 So we are talking about the cache that is happening over here.
01:11:41 Sorry for the pronunciation.
01:11:43 If I make something sound, something different, but yeah, let's talk about this thing briefly.
01:11:49 So what we have, we are demonstrating is that in next years, instead of using some global state context API, or anything.
01:11:58 which will turn our components into client components and we won't be able to get the benefit of the app server side RSC.
01:12:06 So what we do is that we simply make fetch calls in other pages.
01:12:10 So for example, we are making a fetch call in a page and same data that we need in about page, we are just making that call over there.
01:12:18 So what happens is that first time when you visit the page, the cache will be skipped because this is the first time we are making a request to that URL.
01:12:26 But the next time when you visit any pages that are calling the same URL or making the same request that poke API that we are using,
01:12:36 instead of it is making call to that poke API, it will use the cache results that has been stored by next years for us.
01:12:43 So if we go to the .next folder over there, Yeah, that's pretty cool.
01:12:48 So what's happening behind the scenes is Next.js created a wrapper for the fetch functionality.
01:12:56 And Next.js behind the scenes knows immediately that this call has already been made, no matter that we're calling it from a completely different page.
01:13:06 And then it hits it and gets it from the cache.
01:13:09 Is that right?
01:13:11 Yeah, that is completely right.
01:13:13 And that's coming from here, fetch cache.
01:13:15 And it technically generates this file and it's, it's quite hard to see, but you'll see it using cloud fair services right here.
01:13:24 There we go.
01:13:24 We can format it.
01:13:25 I'm not sure.
01:13:27 How can I do that here?
01:13:31 You can right-click it and you will see a format or maybe just control, yes.
01:13:36 Okay, there we go.
01:13:36 That's much better.
01:13:38 I would need to configure the formatter, but yeah, I think this is...
01:13:42 Okay, there we go.
01:13:42 This is much better.
01:13:43 Thank you so much, Sujata.
01:13:45 But now, yeah, you can see that it's using Cloudflare as a server, and then it's caching the responses and sending it back to us,
01:13:53 right?
01:13:53 That is it.
01:13:56 If you see the end of that page, you will see the URL that has been cached.
01:14:01 Yeah.
01:14:03 That's it.
01:14:03 And the reality is right here.
01:14:05 This is amazing.
01:14:06 As I said, I wanted to have Sujata here as well.
01:14:09 It's so crazy that even myself trying to create all these educational videos, it's so hard to stay on the bleeding edge of technology.
01:14:17 And I wanted today to provide you with the latest and greatest of everything we are doing right now.
01:14:23 So all of these demos have specifically been created for you today to be able to go over them.
01:14:29 I think this allows me now to quickly go back into the presentation right here and show you a bit more.
01:14:37 So we talked about this already.
01:14:39 We have a lot of stuff we want to cache specific things, right?
01:14:44 So Sujata, we talked now about fetch cache.
01:14:47 Do you want to kind of keep talking about it or do you want to dive into some other caches as well?
01:14:54 Yeah, I mean, the basic question that I think we would have is that There might be a case that we want to page or use page all the time.
01:15:03 So the question arises that what should we do or how we catch the content or how next year's does that if we don't use page?
01:15:10 For example, we just want to directly make the TP calls inside of our react server components.
01:15:16 So that we catch or not.
01:15:18 So for that, we have our next thing, which is called react cache.
01:15:23 I think it's a hit.
01:15:24 Yeah, that's correct.
01:15:25 So we have seen this all that and it's so easy because we, once again, Next.js makes it amazing because we don't have to do absolutely anything.
01:15:35 You simply have to use the basic fetch call, right?
01:15:39 And that's it.
01:15:39 It works right off the bat.
01:15:41 And you can also set a timer and, uh, tell it to revalidate after specific time.
01:15:46 So here we have time-based, right?
01:15:49 You can revalidate the fetch calls after, for example, uh, this is 3, 3,600 seconds, right?
01:15:56 So you still have, because some people were confused, right?
01:16:00 Think about it.
01:16:01 In our example, we never explicitly told Next.js to cache anything and still it did.
01:16:11 Which you, as a developer, might think, why are you doing things for me, right?
01:16:15 I don't know when you're going to cache it or not.
01:16:17 What if I want to get my data fresh?
01:16:21 Thankfully, we can still revalidate the data after a specific amount of seconds.
01:16:26 We can also revalidate it on demand.
01:16:30 We can extend the Fetch API to decide cache revalidation depending on your specific needs.
01:16:37 There are two ways of doing this.
01:16:39 The first one is the revalidate tag.
01:16:42 So you can add this revalidate tag to the fetch call, next tags, and then say what you want to revalidate specifically once you make this API call.
01:16:53 And then you use it like this.
01:16:55 Use server.
01:16:56 This is a server action where we import revalidate tag from next cache.
01:17:01 And then once this happens, you want to revalidate that specific tag of posts.
01:17:06 We'll see how we use this in use server really shortly.
01:17:10 That's exciting.
01:17:12 Then there's also a revalidate path right here, similar to revalidate tag, but we have to specify the path that we want to revalidate and then have fresh data.
01:17:23 So in this case, we can revalidate posts forward slash slug, which would be a specific post ID after maybe you change the post data.
01:17:32 And you can find further ways in which you can revalidate pages, routes, and more in the revalidate path documentation on Next.js.
01:17:40 So now we have learned cache and how to revalidate it.
01:17:45 But there might be one doubt that you still have.
01:17:48 You might be thinking that can it be cache only when using fetch?
01:17:53 That's the only thing we have done so far.
01:17:56 What if we don't want to use it and rather we want to do direct DB calls in React server components like this?
01:18:04 Where is the fetch here?
01:18:05 Nowhere.
01:18:06 We're using Prisma write to just do a regular fetch from the database.
01:18:11 For that and any other third party solutions, we can use React cache to cache these requests.
01:18:19 Let me show you how to do that in a simple example.
01:18:22 I'm going to open up, once again, our code base right here, and I'm going to give us maybe the fourth, I believe, or yeah,
01:18:30 this is third, maybe, or fourth example of the day.
01:18:35 We're going to call it hello React cache because no longer are we working with just fetch cache.
01:18:42 Here, we have our app.
01:18:43 We can of course navigate to it as before by doing CD and then navigating over to Hello React cache and running npm install to get us started.
01:18:54 Right here, let's first visit our page as we always do.
01:19:01 Here, we're calling two different things.
01:19:05 with cache result and without cache result.
01:19:09 And these are just some simple utility functions that, if we go into them, generate a random number.
01:19:17 And then, if we don't cache it, that's going to look like this.
01:19:21 We're going to simply set this variable to that specific random number.
01:19:26 or rather to a function that's going to fetch, function declaration that's going to fetch that random number.
01:19:31 And then here we cache that response coming from React.
01:19:35 Keep in mind, this is a basic React functionality.
01:19:38 We cache that function declaration.
01:19:41 Then we call them right here and we just display them.
01:19:45 Random number on homepage with cache and without cache.
01:19:50 So let's kind of see how that works.
01:19:55 Same thing here, we're also calling them in a sample server component.
01:19:58 This is server.
01:20:00 And this is also server here.
01:20:01 So we're calling it in two different places so we can see exactly how that's going to work.
01:20:07 And why and where are we seeing this server component?
01:20:10 It's going to be here.
01:20:11 So we display it once normally, just in the regular page.
01:20:15 And then we display the same thing coming from a different server component.
01:20:19 So we can see exactly how it's going to cache the data right here.
01:20:25 We're also doing the same thing in the about to once again, figure out how is it caching it.
01:20:31 So let's kind of run it and see what happens.
01:20:34 I'm going to run npm run dev and open it up on localhost 3000 as we usually do.
01:20:40 And everything should be visible here.
01:20:43 On the page, random number on homepage with cache is 91. Inside of the component, the sample component, the sample server here,
01:20:53 it's 91 as well with cache.
01:20:55 Without cache, we get 6472. But if we refresh, we see a new number with cache, 38 and 38. What's happening?
01:21:09 It's not a bug or anything, it's how React cache works.
01:21:13 It doesn't cache the results across routes, but it memorizes the requests routes we'll make inside of one page.
01:21:21 So let's dive a bit deeper into the topic of request memorization.
01:21:28 What is request memorization?
01:21:30 Well, it's a tactic where if we're sending many requests across various components within a single-pager route, some of which are identical and some of
01:21:42 which are different, React Cache ensures that these requests are memorized.
01:21:48 This means only requests are executed.
01:21:51 If the same requests are made in different locations, instead of making requests for each one, only one request is sent and the data is shared among the
01:22:01 components that initiated those requests on that page.
01:22:06 So once again, imagine if you have that magic helper that can fetch things up for you.
01:22:11 With React magic, if you ask for the same thing, but different parts of your application, so even if it's in different places,
01:22:20 it's not going to fetch it every time.
01:22:22 It's going to try to get it from the cache.
01:22:26 In simpler terms, let's say you have your favorite snack.
01:22:29 And if you want that snack in your room, your living room, and your friend's house, you don't need to go to the kitchen every single time.
01:22:38 React helps you get your snack wherever you are without fetching it from the kitchen again and again.
01:22:46 This is handy because you can get the same information in different parts of your app without worrying about making unnecessary trips to get it,
01:22:57 which makes things faster and more efficient.
01:23:01 However, this occurs at the route level.
01:23:05 To show if I create another page with identical fetch calls, we won't observe the same outcome for cache data as we did on the homepage.
01:23:16 Memoization only applies to that particular route and the components within it.
01:23:22 Okay?
01:23:23 So what if you have things like fetch persisting the same data across the application?
01:23:31 Well, Next.js has got you covered.
01:23:34 Although the team is still working on it, like on many other things, you can use something known as unstable underscore cache to cache your requests across
01:23:45 the routes.
01:23:46 And here we can greet or say hello to unstable cache.
01:23:51 So let's quickly spin up a new project right here where we can close this one.
01:23:57 I think we covered pretty much everything we wanted with this one, Sujata, right?
01:24:02 The way that it caches it across routes.
01:24:05 Yeah, that's the main thing about React Cache.
01:24:08 That's it.
01:24:09 We have seen first just general fetch cache, which caches the fetch requests.
01:24:16 Then we can see, we have seen the React cache, which caches it across routes.
01:24:22 And now we can welcome the next one, which is hello unstable cache, if I can put it right here at the root of my directory.
01:24:33 There we go.
01:24:34 That's another topic we can dive into.
01:24:36 So as usual, let me just open it up.
01:24:39 I did want to provide you with real demos, so it will take some time, but hopefully we'll be able to go through it.
01:24:46 There we go.
01:24:47 And we want to run it and install it.
01:24:50 In the utils right here, the app is still really similar, right?
01:24:53 We have the same thing as before.
01:24:56 We're just building on top of the previous example where we have the get data with cache, get data without cache.
01:25:02 And then now in the utils, we have added getDataWithUnstableCache, where we wrap the function declaration of getRandomNumber.
01:25:13 I see a typo here, but we're going to fix that.
01:25:16 We're going to wrap it with the unstable cache coming from next forward slash cache.
01:25:23 Ready new, pretty exciting.
01:25:25 It's just a simple function as you can see right here, but it does wonders.
01:25:30 Now, what do we do here?
01:25:32 We are adding it to our previous course and similarly, we have it in our homepage, we have it in our sample server page,
01:25:39 and we also have it in our about page.
01:25:42 Same thing as before.
01:25:44 We're importing it everywhere.
01:25:46 So what if we give it a go?
01:25:48 What if I now run npm run dev and try to test it out?
01:25:52 What do you think is going to happen?
01:25:54 On our homepage, we get with cache 22, and of course, it's cached on that specific page.
01:26:00 With unstable cache, it also remains, in this case, generated as 75, right?
01:26:07 So now, if I reload once again, and if I keep reloading, you're going to notice that with unstable cache, it remains as 75. Okay?
01:26:19 Similarly, if we switch to another route right here, if we go to forward slash about, you're going to see that with unstable cache is once again 75. Okay,
01:26:30 same result that we've experienced with Fetch Web API, but this time it's across the routes, not just in one route.
01:26:39 And though the name unstable routes might suggest instability, Next.js team is actively developing it and it's going to be released really soon.
01:26:49 So once again, if I go to the slides really quickly, can you use it in production?
01:26:56 Right now, proceed at your own risk, right?
01:26:59 But hopefully soon enough, Next.js team is going to get it ready.
01:27:04 In fact, the vice president of Purcell right now uses it on his website in production and we can see the code right here.
01:27:12 Pretty cool.
01:27:14 That's a clear signal that it's becoming more and more stable and reliable.
01:27:19 But let's kind of finalize this example and just round it up.
01:27:25 What have we seen this?
01:27:26 What does this even mean?
01:27:28 We have a lot of different things, but the unstable cache seems to just remain all across the entire application.
01:27:36 Is that a good thing?
01:27:37 Is it a bad thing?
01:27:38 How do we modify it?
01:27:40 So Jada, what would you say here?
01:27:41 What is the kind of takeaway of just fetch?
01:27:44 We know fetch.
01:27:45 It's only when we use fetch.
01:27:46 And then we have just the cache and then unstable cache.
01:27:49 What is the takeaway here between those two?
01:27:54 Yeah, I mean, the first thing that we should understand is that Cache is the request for that page or that route that we are using.
01:28:04 But what we get with unstable Cache is the result that we get with any normal fetch calls or fetch requests that we would do.
01:28:12 So there might be a case that we would want it, but again, there might also be cases that we wouldn't want these scenarios.
01:28:18 So we have to first understand what we want.
01:28:22 So for example, you want to build a blog website, you might want to cache these things, all these things.
01:28:28 So you won't make the request to the main server again and again, but instead rely on next year's CDN networks.
01:28:35 So this is where you can use either unstable caching or the React caching.
01:28:40 But yeah, the whole point of it is that doing this, we don't have to use or manage any state management libraries like context API or Redux toolkit or anything.
01:28:51 But do note that it doesn't mean that Next.js is replacing them or just telling them that do not use them at all.
01:28:58 There might be cases that we will still need them.
01:29:00 Without that, we won't be able to proceed.
01:29:03 But if you understand this cache mechanism and just keep on making the calls, considerably knowing what is happening, then you are good to go without the
01:29:11 state management libraries in Next.js applications.
01:29:14 That's correct.
01:29:15 But would you say it's making such a great progress with giving us, the developers, more control over how cache is being handled,
01:29:25 whereas it wasn't doing that as soon as Next.js 13 was out?
01:29:30 Yeah, I do agree.
01:29:31 I mean, if we have to cash anything normally without the next year's.
01:29:35 It's a very hard process.
01:29:36 You have to set up the CDM networks, you have to manage them, all the info and everything.
01:29:41 But yeah, thanks to next year's and Versel infrastructure, all you have to do is focus on the business logic.
01:29:47 You don't have to worry about anything else.
01:29:49 Just understand the concept and trust on Versel that it will handle all these cases for you.
01:29:55 Yeah, it does make the development of the TX very good.
01:29:59 It truly does.
01:30:00 So let's kind of summarize it one more time.
01:30:04 Cache is a special memory storage mechanism used in computing to store frequently accessed or recently used data.
01:30:13 Allowing for faster releases here, it's going to allow us to retrieve it much faster when the same data is needed again.
01:30:24 Next.js has built-in support for cache mechanisms with the help of React features.
01:30:31 Once again, they don't clash.
01:30:33 It's not like saying, you know, React has it at all or React has it as well, right?
01:30:39 It's about merging the two and allowing us to use it with the Next.js as well.
01:30:44 You saw that, for example, for fetch requests, Next.js just wraps it.
01:30:49 Whereas for React cache mechanism, the import is coming directly from React.
01:30:58 And then for unstable cache, that import is coming from Next.js.
01:31:03 Might seem a bit hard right now, but I hope that things will be a bit more streamlined down the line.
01:31:11 Next.js extends the native fetch web API to cache all the fetch requests automatically.
01:31:20 We can opt out of that automatic fetch request caching by providing the no store functionality.
01:31:27 This is, first of all, a very good step on Next.js aside.
01:31:31 Some people found it annoying because they didn't know when things will get fetched and when they wouldn't.
01:31:37 But thankfully we now have this cash no store as well, as well as many other options.
01:31:43 We also have two other ways to revalidate in Next.js.
01:31:46 We have this next revalidate, which is the amount of seconds of when it's going to try to re-fetch it again.
01:31:52 And then we have also on-demand, which is great.
01:31:57 It allows us to revalidate a specific tag, like in this case, where we can revalidate the tag of posts and then recall it in a server action.
01:32:07 We also have a revalidate path right here, where it's going to revalidate a call to a specific path.
01:32:14 We can also use React Cache to cache any third party solutions like Prisma or any calls that are not fetch related.
01:32:22 And we can use Next Cache to cache the data across the application.
01:32:29 Do keep in mind that the discussed revalidation isn't limited to fetch web API.
01:32:35 We can use the same time-based and on-demand cache revalidation techniques with React Cache or Next.js's unstable cache.
01:32:44 And there are two powerful strategies to help us optimize data fetching and reduce JavaScript bundle size.
01:32:52 There is the data cache right here coming from next cache, and there is the request memorization using the request cache.
01:33:00 So it's about figuring out how to use all of these together that will allow us to truly be able to not be mad at the fact that Next.js is caching some
01:33:11 things that we don't want to.
01:33:13 but rather use cache as a way to optimize the data fetching of our Next.js and React applications.
01:33:21 To be completely honest, right now it's a bit all over the place.
01:33:24 The way that they wrap the fetch, which we're not used to, right?
01:33:28 Because we use fetch every single day and we wouldn't just assume that this fetch we're calling is different from the regular JavaScript fetch,
01:33:36 right?
01:33:37 That's one thing.
01:33:38 And then also the fact that we have to call the unstable cache from next or the React cache from React.
01:33:44 Right now, I don't like how it's currently structured.
01:33:49 but hopefully things will get a bit more streamlined with cache in the future.
01:33:53 So although we did explore or actually used it before explaining it, I want to talk a bit more about this properly.
01:34:01 Do you remember when we used the use server instead of utils before for demonstrating the cache?
01:34:07 I want to ask you how many of you have used use server before?
01:34:13 or server actions, or within Next.js in general, have you used it?
01:34:17 Okay, that's interesting.
01:34:19 The use server is a directive similar to use client, and I can see more no's than yeses, but you might have had a gut feeling what this is about to symbolize.
01:34:33 It's something about server things, right?
01:34:36 Normally, they're known as react actions or react server actions.
01:34:42 These are simple asynchronous actions that run on the server.
01:34:48 That's it.
01:34:49 But why do we need server actions?
01:34:51 And let's talk a bit more about them.
01:34:56 So once one more time to explain, we use the use server directive, we add it to a typical JavaScript file, and all the code that is in there,
01:35:06 you can write as regular JavaScript code, but it's going to be rendered in the server.
01:35:12 That's it.
01:35:14 Does it make sense?
01:35:15 So it allows you to provide more simple JavaScript code, but you run it directly in the server.
01:35:22 But the question is, why would we need to do that?
01:35:24 Although I wouldn't say it is a replacement, but instead it is an option to do mutations over traditional route handlers.
01:35:33 We can use these server actions in both server and client components, which makes them a handy feature to use.
01:35:40 While Vercell might be inclined to showcase the use of this feature for form submissions or mutations, we can use them to query things as well.
01:35:51 If you aren't convinced yet, let's see a quick demo and we'll see how useful and handy they are while building an application.
01:35:59 We can create and use server actions in two ways.
01:36:04 in server components where we can add the directive right here, use server directive at the top of a server component inside of any React component for
01:36:15 that matter.
01:36:16 And we can make it async like this to turn it into a server action.
01:36:21 So this is a typical server component where you can create a new async function create where you use server.
01:36:29 The code inside of here is going to be rendered on the server, of course.
01:36:34 Why am I showing you this?
01:36:35 Because we can also use them within client components, which is what makes them special.
01:36:41 The way of using server actions inside of client components is a little different.
01:36:46 Instead of what we did in the server component, we now have to create a new file, declare everything inside of it as use server,
01:36:55 and then import these functions inside of the client components, like this, where we have a new file, use server, create and remove,
01:37:03 and then we can call them whenever we need them to be, be that client component or server component.
01:37:11 such as in this case, as you can see, we are importing create from actions and we know that it is a server component.
01:37:21 In this case, I think I forgot to put it at the top, but it should go without saying, right?
01:37:25 We're using state here, which means that this form is a client-side component.
01:37:30 But the key takeaway here is that we can still use the server action right here.
01:37:36 Okay.
01:37:37 So we have the await create and we call the server action, the handle submit, and then we have the rest of the form, right?
01:37:47 What this allows us to do basically is pretty crazy.
01:37:52 It allows us to make a server-side call within a client component.
01:38:00 Is this clear so far?
01:38:01 I don't want to proceed if this concept is not clear here.
01:38:05 It's a bit counterintuitive because even though we have a client component and all of this code here is client, keep in mind we're using,
01:38:12 we're modifying the data, right?
01:38:14 We're modifying the form, the fields and everything.
01:38:17 We can still call a server action right within it.
01:38:23 Does that make sense?
01:38:24 Okay, it does, which is great.
01:38:28 Now, you might think it's great, you might think that it's unnecessary, but let's kind of explore why we might need to do that.
01:38:36 That would allow us to not create any additional APIs to perform any normal CRUD actions.
01:38:45 In this case, server actions got you covered.
01:38:48 Next.js has made things that simple to do.
01:38:51 But you might think, how do they work?
01:38:55 And how are we able to call a server component or sorry, a server function inside a client component?
01:39:02 Think, how is it possible?
01:39:05 Well, there's no rocket science here.
01:39:07 Server actions we use in client components are basically turned into a post request by Next.js for us.
01:39:16 Okay?
01:39:17 Any kind of server actions, be that getting some information or adding some data to the database, updating it, deleting it,
01:39:26 Next.js calls our server through a POST request, but that is only for server actions inside of ClientComponents.
01:39:36 So Next.js kind of once again abstracts it and makes a server POST request for us from the ClientComponent.
01:39:44 So it's still on the server.
01:39:46 And I can see a question by Halila right here about the concept of using the use server.
01:39:52 It's for server actions.
01:39:53 That's correct.
01:39:54 And it's for differentiating between client side and server side code.
01:39:58 Yes, that's entirely correct.
01:39:59 So we use the use server directive as we would use the use client directive.
01:40:04 We put it at the top of the file and whatever we write in there is going to be executed on the server.
01:40:11 And back to our example with the form right here, if I have to go a way back, but if we didn't put the use server directive right here,
01:40:22 it would render it on the client side.
01:40:24 I think I anticipated your question here, but isn't it by default server side files, do we have to specify it?
01:40:31 Well, Halil, if you didn't have this use server directive right here on these two server actions, and then if you call them right here within your handle submit,
01:40:41 Where would it be called?
01:40:44 What is this code?
01:40:46 Is it client-side or server-side?
01:40:49 By default, it wouldn't be server-side because we're within a client-side component called form.
01:40:56 Does that make sense?
01:40:58 Yeah, I would like to add something over here.
01:41:01 Initially, this was React.
01:41:03 architecture.
01:41:04 Initially they wanted to separate client-side and server-side through file-based architecture.
01:41:10 So if you write inside a name that this is a server.ts or js and that treated as a server component.
01:41:17 But then these flags started as like a more initiative way of writing server and client-side code.
01:41:24 For sure, for RSC, you don't have to specify these because that's what next year's use is by default.
01:41:29 But for anything that you want to do on a server side, just use this flag.
01:41:33 So even if you use this for RSC components, I think they should work as it is because they are already using it behind the scenes.
01:41:41 Exactly.
01:41:42 So in cases where if you were to use this within a server component, then Halil would be right.
01:41:48 It would be on the server by default.
01:41:51 But this allows you to call it within a client-side component as well.
01:41:56 So exactly.
01:41:57 Yeah, you said it's like holding the tool in the data.
01:42:00 So you play it there if you use the use server.
01:42:03 But if you don't specify it, you get the tool and play it in the client side.
01:42:05 That's entirely correct.
01:42:06 Yes.
01:42:07 So I'm really happy that that makes sense right now.
01:42:10 So let me quickly go back to where we were, which is right here, getting some data, uploading it, deleting it.
01:42:17 And yeah, Next.js makes a post request right here.
01:42:21 Let me see.
01:42:23 So for server components, everything is on the server.
01:42:28 And we just finished how things are being done on the client side, right?
01:42:33 But now we want to discuss how things are being done on the server side.
01:42:36 For server components, everything is on the server.
01:42:39 So the component and server function, and everything is executed there.
01:42:44 And then we get the HTML as a streamed response.
01:42:47 So let's create a small application to see the server actions in demo, which is where, once again, we're going to get back to our code,
01:42:56 and create a new folder right here, it's going to be called Hello Server Actions as we're just getting introduced to them.
01:43:05 Once again, we want to cd...cd into Hello Server Actions and run npm install.
01:43:12 And let's see what do we have in store here.
01:43:15 We'll create a complete interactive server-side form using HTML that works even if JavaScript is disabled.
01:43:24 Yep, that's correct.
01:43:26 We have it right here.
01:43:27 It's just a regular HTML file form where we have an action of handleSubmit and we have two different inputs and a submit button.
01:43:35 Cannot get simpler than that, right?
01:43:38 Once we call the handleSubmit, we're going to call this async function handleSubmit that's going to take in the form data Check this out.
01:43:46 It has the use server directive, and then we get the data, we form it into an object, and we simply console log it.
01:43:54 We don't do any DB operations here, but you could if you wanted to.
01:44:00 Now, this works even if JavaScript is disabled because all of this is happening on the client-side form right here.
01:44:08 As a matter of fact, we can test it out.
01:44:11 For showing, if a form submission process or not letting the user keep clicking on the form button while it's processing,
01:44:17 we can then show the form status or disable the button while a request is being made.
01:44:23 To do that, let's go to another page and let's create the same form right here.
01:44:28 We have the interactive and we have the normal.
01:44:31 In this case, we want to go into Let's check out the normal.
01:44:36 Here, we have the loading state, right?
01:44:38 As you can notice, we create a form with two input fields and a submit button.
01:44:43 And when the form is submitted, the handle button will be called.
01:44:47 We can use the states or use form data to get the form values as we do here.
01:44:52 And that's it.
01:44:53 Similar example as we had before, but now we're actually modifying the loading states as well as the error states and the disabled state.
01:45:03 For these, of course, we have to use the state.
01:45:07 Of course, we have to make the useClient component in that case.
01:45:14 This, of course, wouldn't work if we disabled JavaScript then because it wouldn't be able to get all these values, loading states,
01:45:23 and more.
01:45:25 And finally, we have the third example, which is the interactive example right here.
01:45:30 And I think I missed to show the action TS right here in the normal, where we just submit the form, which does a, which is a server action that submits
01:45:39 the form right here.
01:45:40 Let's dive a bit deeper into this Sujata.
01:45:43 How would you explain the way we're using it right here, the handle submit?
01:45:48 Yeah.
01:45:48 Can you go back to the main page file?
01:45:51 Of course.
01:45:53 Yeah, over here, if you notice, we are not doing any kind of server-side or sorry, client-side things.
01:45:59 It's purely a server-side firm.
01:46:03 And even if you disable JavaScript, that should work.
01:46:05 Yes, we can maybe test it out, right?
01:46:09 Yeah, we can test it out.
01:46:10 Yeah, just to show it, I think this is a really good example to explain how the client side and server side stuff works.
01:46:16 So if we go right here, and if we just go to inspect, I think we should be able to just try it out and send it.
01:46:23 So let's do Adrian and let's fill it out.
01:46:26 So if I do this, if we go to, I believe we're cons logging it.
01:46:30 There we go.
01:46:31 We can see it right here.
01:46:32 What I could do is I could also disable JavaScript.
01:46:36 I believe I have to go to here, right?
01:46:42 So Jada, do you know where it is?
01:46:43 Over here, if it's going down, there should be a disabled JavaScript option.
01:46:49 So yeah, I don't, I don't use that too much.
01:46:52 Uh, let's, let me just go through it.
01:46:54 It should be somewhere here.
01:46:57 Is it all the way down?
01:46:59 Yeah, all the way down.
01:47:00 Okay, there we go.
01:47:01 And then disable JavaScript.
01:47:02 There we go.
01:47:03 I don't use this too often.
01:47:04 I believe none of you maybe do.
01:47:06 Or maybe your bosses made you test your web applications, even if JavaScript is disabled, which is not happening often nowadays,
01:47:14 but still, it's good to check.
01:47:16 If we do it, I don't believe I have to reload, but I can, I guess.
01:47:22 So if I reload, JavaScript is definitely disabled.
01:47:26 And now I can just do a test.
01:47:30 And you should be able to see that it gets processed normally, even without JavaScript.
01:47:36 Now, on the other hand, if we go to the second page, which is the normal right here, so that's going to be normal, the way we're used to doing things right now,
01:47:46 Here, we should have some disabled states and loading states as well.
01:47:49 So if I do the same thing once again, we see submitting, right?
01:47:53 Which is pretty cool.
01:47:54 And we cannot re-click it if it's submitting it.
01:47:56 Cool thing, right?
01:47:57 Adds interactivity.
01:47:58 But if I disable JavaScript, I don't think it did too much, right?
01:48:04 Let's check it out once again.
01:48:07 Yeah, it didn't do anything.
01:48:09 It didn't submit it because it cannot without JavaScript.
01:48:12 It doesn't know if this button is disabled or not and it cannot call this thing right here, which is the handle submit without JavaScript because it's
01:48:23 using states, of course, in this case.
01:48:26 Um, what we can do is, uh, oh, you're right.
01:48:30 Uh, we can also go back and I can check the client side code right here as well, because we are on the client side after all.
01:48:37 So if I go back here, and if I go to next JS, if I go to forward slash normal, and if I open up the inspect element right here,
01:48:50 go to console and do this.
01:48:56 No, nothing.
01:48:58 And then even if we go to our, once again, I have to disable in here as well, preferences, disable JavaScript.
01:49:05 Not sure if I have to reload.
01:49:06 I'm just going to do that anyway, to be sure.
01:49:09 And if I now type it, no, absolutely nothing is happening.
01:49:13 We get absolutely nothing in the client console as well.
01:49:16 So it just stops our app from working.
01:49:19 Now, I want to also- Yeah, there is a reason for that.
01:49:23 Just to clarify the question, it's because we are using that console log server side.
01:49:29 So it will never go to the client side.
01:49:31 That's correct.
01:49:32 It's happening right here.
01:49:34 And then we use the handle submit.
01:49:38 and we use the submit form, right?
01:49:39 And the submit form is actually using the use server directive.
01:49:44 So that's the reason why we tried to submit it to the server.
01:49:46 That's the idea, right?
01:49:48 And this then, this allows it from happening and this will disallow it from showing up on the client side.
01:49:55 On the other hand, we are coming to the latest example, which is the interactive app right here.
01:50:03 So we are under server actions app interactive, where we have a page right here.
01:50:09 Let's go ahead and explain it.
01:50:11 So this is a demo to show how to do loading and error handling with server actions within a form.
01:50:17 We have a function where we have the same form as we had before.
01:50:21 We have the form that calls the handle submit, and this handle submit is a use server action where we get the data, and then we wait for a few milliseconds
01:50:30 to simulate a slow server, two seconds right here, and then we console log in.
01:50:35 How is this different from the first example, Sujata?
01:50:38 Why would you say this matters?
01:50:41 Yeah, over here we are, I mean, if we see the first page, over there we are not showing any kind of state on what is happening when we click on the button.
01:50:51 Is it submitting?
01:50:52 Has it submitted anything?
01:50:54 But here we have a special button, right?
01:50:57 Yes.
01:50:58 Yes.
01:50:59 So this button, check it out, is using the use client state, or rather using the use form status coming from React Dom.
01:51:10 which is pending.
01:51:11 And then if it's pending is disabled and based off of that, we can set the submitting or is submitting.
01:51:17 So we're using a client component within a server file, which is a form.
01:51:25 And this form is using the use server directive to submit it back to the form.
01:51:29 Is there anything you would like to add with this example, Sujata?
01:51:34 Yeah, I would just talk about that custom component button a bit.
01:51:39 The use form status that we are seeing where there is a new type of hook provided by React, basically, which keeps tracks of the last form you are submitting.
01:51:48 And depending upon that, it shows the state, whether the form has been submitted, successful, unsuccessful, and everything.
01:51:54 And we get that via that pending that we are using inside that button file.
01:51:59 Pretty cool.
01:52:00 But even if we didn't use it, we would be able to just set a use state field, right?
01:52:07 Or in that case, would we have to turn our form into an actual client side form, right?
01:52:12 Yes.
01:52:12 And that is what we did with the normal page.
01:52:17 And then it didn't work without JavaScript.
01:52:21 Yeah, we can taste this now.
01:52:22 Whereas in this case, using the React DOM, using the use form status right here, if we go back to our current application,
01:52:30 let me just open it up right here.
01:52:33 And if we go to, I believe it is interactive, same form, right?
01:52:39 But now, if we enter it, and if I do it like this, Submitting, we saw the state, right?
01:52:47 You saw the state.
01:52:48 And if we go back right here to our code, you can see that it actually submitted it.
01:52:53 Nothing crazy, right?
01:52:55 But if I go here and if we go to our preferences and disable JavaScript right here, There we go.
01:53:06 Reload the page and then test it disabled.
01:53:10 Let's say disabled.js at gmail.com.
01:53:14 And if I click submit.
01:53:17 Okay.
01:53:17 We don't see the loading state, but what we do see here is the new message.
01:53:24 So even with the disabled, we got it through to our server.
01:53:29 That is the idea.
01:53:33 And that's how we can use all of these different states from React and how we can use server components, okay?
01:53:41 Similarly, we can do similar things with error management, right?
01:53:45 Using another special hook from React hook form called useFormState, which is what we have seen right here.
01:53:51 It's not only for the pending states, it allows us to handle error management as well.
01:53:56 I can quickly pull up our use form right here coming from the official React docs.
01:54:03 You can see that, I believe, I'm not sure if it's ready yet.
01:54:06 No, it's not.
01:54:07 You can see that it is still in progress of getting there, but it allows us, pretty soon you'll see it all across the page,
01:54:14 right?
01:54:14 It allows us to just get the state and the last form action of that specific hook.
01:54:20 And then we can use it or of the form, sorry.
01:54:23 And then we can use it and based off of it, we can do some, some future changes right here.
01:54:28 Okay.
01:54:32 I think that's more or less it when it comes to these, to this example of server actions.
01:54:40 Let me quickly see.
01:54:41 We have used only a small example here, but it is such a powerful feature and you're absolutely free to do any kind of complex scenarios using these server actions.
01:54:53 To show you what I mean, let me open up the repository of my Next.js course.
01:54:59 In this course, we cover querying and complex mutations and a lot of other stuff.
01:55:05 So this is the repo that I have right here.
01:55:09 And let me just pull it up right here so you can see it.
01:55:12 Here we go.
01:55:17 Let's go into where we're calling these server actions.
01:55:20 I believe I can press the dot and it's going to open it up directly in our editor right here.
01:55:26 That way we'll be able to more easily see what's happening.
01:55:30 We dive into tasks and fetching recommendations or conducting global searches.
01:55:35 A lot of stuff will be happening here.
01:55:38 So let's specifically dive into our lib actions.
01:55:43 And then you can see for all of these different types of actions, I have created a new page and we use the use server directive on the top.
01:55:51 So this is a production example of a proper way to use server actions.
01:55:55 And these are pretty hefty server actions.
01:55:58 As you can see, we call the exportAsync function createServer, we connect to our database because it is a serverless architecture,
01:56:06 we get the params, we make a modification to the database, and then re-validate the path.
01:56:11 So we're using a couple of concepts we discussed so far.
01:56:15 Okay?
01:56:17 Pretty cool stuff.
01:56:18 And the way we use it, of course, is let's see where create answer.
01:56:23 We call it right here within the answer file, which conveniently in this case is a use client component, but we can call the create answer or get answer
01:56:33 or any other async server actions that we have created.
01:56:38 That's the power of these server actions.
01:56:42 Uh, now quickly going back to our code base or to our slides right here.
01:56:50 Pretty cool stuff what Next.js allows us to do with those.
01:56:53 But there are a couple of kind of concerns or issues about using Server Actions.
01:57:00 Thankfully, Server Actions, first of all, the first concern was that they were not stable, right?
01:57:05 But then they became stable as of Next 14. There are a couple of things.
01:57:11 Let me see where I am right with the slides.
01:57:14 This meme was the largest meme of the Next.js 14 conference.
01:57:20 It was trending all over Twitter and Reddit where we have a function bookmark that returns a button and within a button,
01:57:28 we use a form action that calls SQL directly within it, directly within the client-side code.
01:57:36 And people got a bit confused, thinking SQL is now directly inside JSX.
01:57:40 Some even remembered their PHP days and started making fun of it.
01:57:47 But like I mentioned earlier, it's not actual code that's inside of the component, even if it looks like it.
01:57:54 Negus.js will turn it into a post request behind the scenes.
01:57:59 And when it comes to security, you can use anything inside a server action to check the input first before making actual DB operations.
01:58:07 And here I have an even an example of doing that.
01:58:10 So we're doing an example where we check the schema of the name and the email, and only if we validate the fields and if they're safe to parse,
01:58:19 only then can we make any calls, right?
01:58:22 So you can still make them secure.
01:58:25 You can also add as many security measures as you want to make it safe.
01:58:29 It's completely in your hands.
01:58:31 And while server actions might be cool thing to try, and they are, there are some drawbacks too.
01:58:38 First of all, you can't use server actions or cross-platform development where you need the same backend or same API on different ecosystems like mobile
01:58:50 or desktop.
01:58:51 Server action endpoints can be exposed as of now.
01:58:55 So it's not like you're creating different API endpoints that you can just reuse across different frontend applications.
01:59:03 Server actions also can be used for scenarios like webhugs or sockets, because in these cases, you need a server always listening for event updates,
01:59:14 which server actions don't support since they are an integral part of the server and are not exposed.
01:59:23 Also, testing might feel challenging with server actions because you can't use tools like Postman and testing has to be done directly.
01:59:32 On the positive side, it does enhance security since your API isn't exposed.
01:59:39 And for some, using post requests or events like updates or deletes may not align with best practices of HTTP protocols.
01:59:51 But overall, it's best to use them if you want to build and ship applications faster.
01:59:57 That's where they shine in improving the developer experience.
02:00:02 And I've showed you the example right here.
02:00:05 not this one, but the much larger one within our course, where we have a huge application and we use server actions to just simplify it.
02:00:15 Because instead of creating many, many different API routes right here, we do have some, right?
02:00:21 But we don't have many because we have opted for using the server actions to interact with their database instead of creating many different API endpoints.
02:00:32 That's why we like them.
02:00:33 They improve developer experience and make writing your code seem like writing normal JavaScript and normal React, whereas you're really interacting with
02:00:43 the database within these functions.
02:00:47 There's more topics to talk about.
02:00:50 And the next topic would be, if I could get right in here, edge versus node runtime.
02:01:00 It's going to be one of our last topics for today.
02:01:02 But before I proceed with it, I do want to give you some more time to get a pause.
02:01:07 So we're going to pause again for about 10 minutes, five to 10 minutes, and then we'll be right back to finish it off with edge and node runtimes.
02:01:16 Just a quick intro.
02:01:17 I don't want to dive too deep into it because I know that it's impossible for you to keep your Just keep your enthusiasm,
02:01:26 first of all, if you had any other start, but to keep your focus for two to three hours.
02:01:32 These workshops are great, especially if they span across the entire day.
02:01:36 But like this, it's so tough to just get everything in, which is, again, why I want to emphasize the point of just revisiting these examples and revisiting
02:01:46 the presentation as well.
02:01:47 So I'm going to share with you most likely a Figma link to this entire presentation that you can visit later on.
02:01:55 We're going to talk about edge versus node runtimes.
02:01:58 Just about figuring out once we ping our servers, which server are we going to ping, how far away from us is it, and how fast the response time will be.
02:02:12 It's nice to see you guys.
02:02:13 I see you also on cameras now.
02:02:17 I'm glad you're back with me right now.
02:02:20 So, can you all hear me well?
02:02:22 Ready to hear?
02:02:23 Ready to proceed?
02:02:24 Yes, sir.
02:02:26 Amazing.
02:02:26 Awesome, guys.
02:02:27 You're here two and a half hours, guys.
02:02:29 I thought it was going to take a bit less, but you're still here.
02:02:33 Once again, now that I revisit this material, it's almost incomprehensible in one sitting.
02:02:43 So, I apologize in advance and then right now for cramming it up with so much information, but just wanted to put everything in here.
02:02:52 I can send you the presentation.
02:02:53 I can send you the examples as well.
02:02:55 So you can later on look at them and then review them and even ask questions on Discord.
02:02:59 So just wanted to provide as much as possible here.
02:03:04 With that said, I want to talk about edge versus node runtimes in Next.js, but specifically here, I want to dive into another code example.
02:03:15 So what we can do here is I'm going to provide you with another little folder, which we can open up right here.
02:03:23 There we go.
02:03:24 It's going to be called Hello Edge.
02:03:26 And we can once again just dive into it by cd-ing into hello-edge and running npm install.
02:03:36 Or maybe, I know that Yarn is more popular nowadays.
02:03:39 I might transition to Yarn really soon.
02:03:42 But let's see what do we have here.
02:03:44 We have a page and this page is just typical Next.js page.
02:03:48 It didn't change it too much.
02:03:52 But what we can dive deeper into is the API folder.
02:03:57 So now we're not talking about server actions.
02:03:59 We're talking about Next.js API endpoints and the way to expose them.
02:04:05 And I can see Achilles saying that, you know, it's good to hear about all of these different things.
02:04:11 And now we can choose which topics you want to go into deeper, which is good.
02:04:15 I'm really glad you found it that way.
02:04:18 Let's look into the node right here.
02:04:21 This is a typical API route, route.ts under a specific folder where we import next response.
02:04:30 we create an export async function get, and then we purposefully delayed the response by one second.
02:04:37 So we just await it, we await it, and then we return the response, hello from node runtime.
02:04:44 That's the first example.
02:04:45 The second one is getting it from the edge example.
02:04:49 Again, same exact thing, but the only thing you have to do is export const runtime edge.
02:04:56 Once again, Next.js makes it so interesting and so simple to modify a huge factor like this, like changing the runtime by simply running export const runtime
02:05:06 and then modify it.
02:05:08 Okay.
02:05:09 And then finally we have a dynamic node, which we're going to dive deeper into.
02:05:14 Again, just another little flag that you add called force dynamic on the dynamic flag right here.
02:05:21 So now we would definitely want to deploy this application.
02:05:26 Let me see if I can quickly pull up a photo of a deployment of this app.
02:05:31 I think I can get it right here.
02:05:34 There we go.
02:05:36 You should be able to see it if I can quickly drag and drop it.
02:05:40 There we go.
02:05:41 So this is, if you deploy your application, this is how it's going to look like on Vercell.
02:05:46 You can see we have Next.js, you can see static assets right here, and you can see different functions.
02:05:51 Specifically, if your API is deployed on edge, you're going to get this edge mark, this edge icon right here.
02:06:00 Okay.
02:06:02 Now, I didn't explain anything about why we might want to use different runtimes and how do they actually work.
02:06:09 So let's get a bit deeper into that.
02:06:13 What I might want to do is let me first pull up my presentation right here and then dive into that right from the example.
02:06:22 We talked about a lot of rendering strategies, right?
02:06:25 We talked about static, dynamic.
02:06:28 We also had the environments, the server, client, node, edge.
02:06:32 A lot of things was happening during this two and a half, three hours, and a lot of things is happening in Next.js as well.
02:06:40 But specifically, we can see when talking about runtimes that they have something to do with the server.
02:06:47 Where is this server targeting?
02:06:48 Is it targeting Node or is it targeting Edge?
02:06:51 And let me tell you a bit more about both of them.
02:06:55 In this case, Edge runtime is like having a mini computer close to where you are or where your devices are.
02:07:03 So instead of doing everything on a far away big computer, it does some tasks nearby.
02:07:10 Okay.
02:07:11 This makes things faster, especially for stuff like websites, smart devices, or anything that needs quick responses.
02:07:19 It's like having a helper right next to you instead of calling someone far away for every little thing.
02:07:26 So when I say node, I actually mean Node.js runtime, right?
02:07:32 So how does Edge, which is Next.js's Vercelles runtime compare to Node.js runtime?
02:07:39 Well, let's compare it.
02:07:41 First, let's start speaking about a location.
02:07:44 The edge runtime runs at the edge of the network, closer to the users.
02:07:50 Whereas the Node.js runtime runs on server clouds or servers cloud, sorry, and local machines, right?
02:07:56 So it can be run anywhere, typically on a server.
02:08:00 Both have their own unique purposes.
02:08:03 Edge runtime is specialized for quick and efficient execution of code in distributed locations.
02:08:10 So it's distributed across the globe.
02:08:13 Whereas node is general purpose runtime for executing JavaScript code as we all know.
02:08:20 Further differentiating it, we can talk about implementation.
02:08:23 Example is Vercell's edge runtime built on high performance V8 JavaScript and WebAssembly engine.
02:08:30 Whereas on the other hand, Node.js is widely used for server-side scripting and development.
02:08:36 And talking about use cases, edge runtime is geared towards low latency.
02:08:43 where we want to just deliver the content really fast and quick and process all of the tasks near where our users are located.
02:08:51 Whereas the node runtime is versatile for a wide range of applications from web servers to command line tools and server-side JavaScript applications as well.
02:09:01 So while there are specific use cases for both, both have limitations.
02:09:06 Here are some limitations of the edge runtime.
02:09:09 It's constrained environment, which means that edge runtimes are often more constrained compared to full server environments,
02:09:16 limiting certain capabilities that we want to use.
02:09:19 Flexibility is also reduced because they may limit range of applications compared to more general purpose runtimes.
02:09:27 And then dependency on network.
02:09:29 Well, since edge runtimes are distributed globally, they depend on network conditions and issues may arise in network disruptions.
02:09:39 Whereas limitations of node runtime is potential cold starts because serverless implementations of Node.js may have cold start times causing a slight delay
02:09:50 when a function is invoked for the first time.
02:09:53 Resource consumption, where no JS is a lightweight resource consumption can still be consideration, especially in scenarios with limited resources.
02:10:04 And finally, let's say DL for ultra low latency.
02:10:09 Where you need ultra low latency, the centralized nature of Node.js runtime may introduce some latency compared to edge runtimes.
02:10:19 So we have figured it out, both have their advantages and disadvantages.
02:10:24 And if I have to suggest something, then I will suggest do things depending on your needs.
02:10:30 Vercell, who has built its own edge runtime, shares a nice difference between all of these features and which features do edge and node support in Next.js applications.
02:10:42 So here we can see that, again, you have to figure it out for your own, depending on which features do you need.
02:10:48 Are you worried about security?
02:10:50 Then you might want to use exterior securities high in edge environments.
02:10:55 Are you worried about latency?
02:10:56 Then, and if you need really low latency, you can get low latency in edge.
02:11:02 But on the other hand, if we look into, let's see, MPM packages, all are supported here, but only a smaller subset of them is supported on edge.
02:11:12 So it depends on what you need.
02:11:16 Yeah, and also static rendering is not supported on edge, whereas it is on the node environment.
02:11:21 Once again, it depends on exactly what you need.
02:11:25 So let's understand what edge and serverless functions are and when to use them.
02:11:32 An edge function is a piece of code that runs on the server at the edge of the network, closer to the user.
02:11:40 It is smart and a quick responder.
02:11:43 It does the job near you, making things faster and especially for applications that need immediate actions like handling website requests or managing data
02:11:53 from nearby devices.
02:11:56 There's a lot of stuff happening right here.
02:11:59 And once again, you can compare the edge functions with serverless functions similarly to how we compared the runtimes together.
02:12:08 And a lot of you that work with AWS may compare this with Lambda functions as well, as they're also serverless.
02:12:16 It's a completely valid consideration to make and a comparison to make as well.
02:12:24 I don't want to go too deep into this.
02:12:26 You will have the slides.
02:12:27 We're going to mostly likely provide you the script as well and a lot of different information on this.
02:12:32 So it's definitely something that you can read more into the slides right here.
02:12:37 I know we're getting close to three hours already and I don't want you to take the full three hours and maybe more than that if we dove too deep into all
02:12:46 of this.
02:12:46 I hope you're okay with me doing that.
02:12:49 But once again, both have their own benefits and advantages and disadvantages.
02:12:54 You have to think about what exactly do you need, right?
02:13:00 Moving on, we have to understand How can we change the runtime in Next.js?
02:13:06 Let me see if I can do that here.
02:13:09 We already went through it in a quick example.
02:13:11 It's just a matter of fact of switching that export cost runtime, which brings me back to my example that we have previously seen,
02:13:22 which is running right here.
02:13:24 If I can pull it up, there we go, which is why would we decide to use which one and how can we notice the differences?
02:13:33 If I can quickly pull up a postman response or a request that I've done, we can see it right here.
02:13:41 There we go.
02:13:42 We can see that if we do a hello from no runtime, it took about 2.76 seconds to give us back the data.
02:13:52 If we check out the same example, calling the same function we have in our example from the edge runtime, it's going to take Place your bets right now
02:14:03 if you want to, but it's going to take about 1.8 seconds, which is a second less, which is a huge difference that we have right here.
02:14:14 What else could we kind of cover right here?
02:14:17 Let me see.
02:14:18 So in this case, Edge is preferred, of course, if it works with all of the other parameters that you want your app to have,
02:14:26 because it's located on a server that's near to me.
02:14:30 That's it.
02:14:31 On the other hand, node runtime that we have seen right here that takes 2.7 seconds is located in a server used by Vercel at deployment,
02:14:40 which could be far away from when compared to the other edge runtime.
02:14:47 That's good.
02:14:48 Let's quickly open this up right here, go back to the presentation.
02:14:53 And the question is, should we use edge over node, right?
02:14:57 It makes it obvious.
02:14:59 It's going to take one second less.
02:15:01 The answer to that question is not at all.
02:15:04 Edge has also its own limitations.
02:15:07 And these include quick, but not infinite.
02:15:12 Edge functions need to respond within 25 seconds initially.
02:15:16 So they're like speedy helpers, but they can't take forever to do their job, right?
02:15:22 In case it takes more than 25 seconds, they're going to expire.
02:15:26 You have to watch the size because these functions can handle up to four megabytes of data, including all the code.
02:15:33 It's like having a small backpack, fit what you need, but not everything.
02:15:38 Also, mind distance.
02:15:40 If your data source is far from the edge function works, it might take a bit longer.
02:15:45 It's like asking a friend to do something, but they need to travel a bit first.
02:15:50 You can tweak the settings to reduce that travel time.
02:15:53 And finally, not all tricks are allowed.
02:15:56 Some cool trips like the JavaScript knows Edge functions might not.
02:16:01 It's like having a special toolbox where not all the tools are there.
02:16:05 You can check a list of tools that we discussed before, right?
02:16:08 Some limited API functionality.
02:16:12 Let's see.
02:16:13 So that's clear.
02:16:15 But again, when should we consider using Edge over node runtime?
02:16:20 That's a question.
02:16:23 And once again, we get back to, it depends.
02:16:27 It depends on what you need, right?
02:16:29 And here are some questions that I ask myself.
02:16:32 What's the nature of your feature?
02:16:35 Is it a latency sensitive task?
02:16:37 If it's not, simply use a Node.js runtime or serverless functions.
02:16:42 It works just as well.
02:16:44 Well, if it is a latency sensitive task, Is it crossing edge limitations?
02:16:49 Do you need to use some APIs which edge functions don't have access to?
02:16:54 If it is, then go back to using Node.js runtime.
02:16:58 And if it's not, use edge runtime or edge functions.
02:17:01 Okay.
02:17:02 So always remember to check specific use case, depending on the constraints and depending on what you want to do to make an informed development decision.
02:17:13 And here are a few use case examples of edge runtimes.
02:17:18 I want to ask you maybe, let me do that first.
02:17:21 Do you have an example of where you might want to use edge runtimes instead of node?
02:17:28 One example are, yeah, instant messaging is a great example, and I think on the same the same idea is notifications or live messages,
02:17:38 right?
02:17:39 That's actually great.
02:17:41 Edge functions can be used to push real-time notifications or messages based on their location, providing instant updates without relying on centralized servers.
02:17:53 Great, great work.
02:17:55 Also, authentication and authorization.
02:17:59 Handling user auth at the edge can reduce latency for login processes, enhancing the login experience, which we have to do so often.
02:18:09 And also geolocation services that we discussed right here.
02:18:13 Implementing location-based services such as geolocation tracking or local recommendations by processing location data at the edge.
02:18:21 And there are many similar use cases.
02:18:24 Edge functions are also often used in CDNs to deliver web content like images, video, scripts from servers closer to users.
02:18:34 CDN, right?
02:18:35 Now that you talk about it, it's quite similar to what we have been explaining or describing edge functions as.
02:18:42 This reduces load times for websites, improving the overall user experience.
02:18:49 That's something we learned already.
02:18:52 So that's about it.
02:18:54 Edge versus node runtimes, edge versus serverless functions, when to use them, how to use them, and everything else.
02:19:02 Um, and, um, Halil, I can see one question more is, and that is how can we enable edge?
02:19:09 And your, uh, question is entirely right.
02:19:12 We just add runtime edge where you're calling that request.
02:19:17 And that's it.
02:19:18 That immediately makes your, uh, call, uh, based off of the edge endpoints right here.
02:19:25 Expert cons runtime is edge and it just works right off the bat.
02:19:31 One more thing I want to talk about is that now that we're at the final part of this workshop, I hope you gained a lot of knowledge and kind of got at
02:19:45 least a little part of what you were looking for.
02:19:48 Using all of these features we learned is amazing, but if people don't see it, then there's no need to use those features after all.
02:19:57 It's kind of atypical that think that development is sometimes the easy part, but the marketing is the hard one, right?
02:20:04 We build these websites for people to use.
02:20:08 So it's our responsibility to find a solution in a way that's going to give us a lot of traffic on our site and make it noticeable on a sea of different
02:20:20 websites online, right?
02:20:22 And there are many ways to do that via the non-developer way, meaning that your company or your teams can either create ads,
02:20:31 funny memes, or a lot of social content and stay active on all of those.
02:20:37 But this is a non-organic traffic, meaning that you have to pay to get some traffic.
02:20:42 On the other hand, organic traffic is what we as developers can do inside of our code, where crawlers would be able to index them properly on search engines.
02:20:55 And I think you can see where I'm going with this.
02:20:59 The last topic of today's workshop is SEO, right?
02:21:05 How can we impress different picky cats right here to visit your website?
02:21:13 Well, imagine your cat is the internet and it only pays attention to the shiniest, most interesting toys, which are websites.
02:21:21 So if SEO is your way of making your website the coolest, sparkliest cat toy in the room, we can use the right tricks, which are keywords,
02:21:32 arranging things neatly on the site structure and making sure your cat enjoys playing with it, which is the user experience.
02:21:39 And the better you do this, the more your cat or the search engine will show your awesome toys to other users, resulting in more people to use it.
02:21:49 Of course, this is a whole topic in a workshop on its own and not necessarily fully related with what we're talking about,
02:21:57 which is Next.js, but there are many ways on how we can work with those in Next.js.
02:22:05 So I just want to quickly go over this.
02:22:07 You can improve SEO by improving keywords, right?
02:22:11 Making sure they're labeled properly and crawled by the websites.
02:22:14 You can improve the content quality of your websites by creating high quality lead magnets for users.
02:22:20 You can write better meta tags on your websites as well, or improve your website structure as well.
02:22:27 That helps with SEO too.
02:22:29 A well organized structure helps quite a lot.
02:22:33 You can improve your site speed, which is another thing, to have kind of express lanes to visit your website, because users don't want to wait anymore.
02:22:42 It has been proven that Google ranks websites with higher speed times or low times more highly on the list than other ones.
02:22:52 Backlinks as well, we need to put a lot of backlinks and we need to clear our URLs, but there's a lot of things that we have learned so far.
02:23:02 But how can we actually add that metadata to our application?
02:23:07 That's something we want to discuss further in Next.js specifically, right?
02:23:11 I want to skip this part.
02:23:12 You can read it later on.
02:23:14 Most of you know what SEO is and what you can do, but how can we do this in Next.js?
02:23:20 There's two ways.
02:23:21 We can do it using the config or, and let's dive into the config part a bit.
02:23:28 We can do that by creating both static or dynamic metadata objects using the Next.js's API of metadata.
02:23:40 We can do it statically, like this, where we can just write export const metadata, JS Mastery, and then write a description,
02:23:48 and that's going to get added to your site's metadata.
02:23:51 It's static.
02:23:53 Any content within the title here will be added to HTML title tag and description will be turned into the meta tag.
02:24:00 So the above output will just return this title in the meta with the description.
02:24:07 Pretty cool and easy way to add metadata.
02:24:09 We also have dynamic metadata.
02:24:12 If there are dynamically generated websites or dynamic routes that we want to search engines to index, which is a best practice,
02:24:21 we can use the generate metadata function from Next.js to produce metadata specifically tailored to these pages.
02:24:29 For example, to show you, I have implemented this strategy on the JavaScript Mastery website for resources, where we host different resources people can
02:24:38 learn from.
02:24:39 And you can see different titles and descriptions.
02:24:43 And if you click on one of these resources, you'll see a change in the title and description as well.
02:24:47 Let me quickly open it up and just pull it right here.
02:24:53 I think I have done it.
02:24:54 There we go.
02:24:55 And if I go into one of these, we can see that right now the URL is just resources.
02:25:00 But if I navigate over to this one, we can see resource and then a specific ID here.
02:25:06 And you can also see the title of the website changes to the ultimate React Native part.
02:25:11 We also have different ones for Next.js and so on.
02:25:14 So the title, description, and everything else changes.
02:25:18 Nothing new, right?
02:25:19 We were able to do things like these before as well, but now Next.js makes it so easy to do that.
02:25:25 So this is what dynamic metadata is.
02:25:30 And achieving this is super easy.
02:25:33 You just call the generate metadata, you pass the params, and then you render the title by getting the resource title from the database or whatever else
02:25:42 you're getting it.
02:25:43 And then you can also modify all the other tags like this SEO description, OG images, right?
02:25:50 Titles, Twitter titles, Twitter descriptions, and more to ensure that all of your routes look good.
02:25:57 And finally, there's the file-based metadata, where we can put things like robot files, robot.txts, favicons, sitemaps, open graphs,
02:26:07 and more.
02:26:08 But do note that file-based metadata has higher priority and will override any config-based metadata.
02:26:17 And I have prepared one final demo example for SEO for you, but I think we can skip it.
02:26:27 I hope that's going to prompt you to actually open up not only this SEO metadata file-based example, but also all the other ones once you're checking for
02:26:37 this one.
02:26:39 So we covered a lot of ground right here.
02:26:44 And I'm a bit out of breath to be completely honest, but I do hope that you have found this valuable and I hope you learned a thing or two about Next.js,
02:26:55 about React, React server components.
02:26:58 And that's it.
02:27:00 Do you have any thoughts so far?
02:27:01 Do you have any additional questions?
02:27:04 I'm hoping that we can kind of continue this discussion on Discord.
02:27:09 I didn't yet open it up myself or I haven't been looking at it so far on my screen, but I guess I can quickly get it running right here and we can see
02:27:20 what's happening.
02:27:22 If I open up Discord and if I pull it up right here, we should be able to see it together.
02:27:30 There we go.
02:27:30 It should be here.
02:27:31 So if I open this up, It's under the Git Nation Discord.
02:27:37 They have created it for us.
02:27:38 It's a forum right here posted 52 minutes ago.
02:27:41 And we can see Vanessa greeted us.
02:27:44 And we can keep all of the questions related to this workshop right within this Discord forum right here.
02:27:51 It's created and hosted by Git Nation, but I think they're going to allow us to just keep the communication going, share all of the useful links and everything
02:28:00 else that we might find and share with others.
02:28:04 You guys had some great questions today, but I'm sure that you will have many more specific questions, maybe more tougher questions,
02:28:12 once you maybe think about this and once this settles down a bit.
02:28:17 Yeah, right?
02:28:19 Let me just go through comments quickly.
02:28:21 Yeah, so Jada really conveniently shared the GitHub repo as well.
02:28:26 So in this GitHub repo, we are able to go through all of the examples very nicely.
02:28:31 We're going to link it to Discord as well.
02:28:34 So you can reopen them, test them out.
02:28:37 The examples are incredibly minimal, which would allow you to just really nicely take what you need and then implement them on your own projects.
02:28:49 On this topic, I want to thank Sujata as well for being here answering a couple of questions.
02:28:53 I wanted to have her.
02:28:56 She's a part of a team.
02:28:59 She was able to answer some of your questions in the chat as well as jump into the call.
02:29:03 So yeah, huge thanks to Sujata as well.
02:29:06 Yes, Simon, we will look into the way of providing you with the slides too.
02:29:11 They might be a couple of gigabytes even when compressed because there's a lot of slides, but we might share a Figma link to those slides as well on Discord.
02:29:21 Every piece of information that I can get for you guys, I'll prepare it and I will drop it in this link on Discord.
02:29:31 Just so we don't lose it, I want to copy it and I'm going to drop it right here.
02:29:37 Let me see.
02:29:41 There we go.
02:29:41 I'm going to paste it in the chat right here.
02:29:44 So one more time, if anybody cannot find it, you have it.
02:29:48 Let me just go through your comments.
02:29:49 I can see a lot of great words, people saying that they like the workshop.
02:29:54 I'm really happy to hear that.
02:29:57 And I want to thank you, not me for doing this, but thank you for being here and actually dedicating three hours of your Friday today to be with me and
02:30:08 to learn about Next.js.
02:30:11 I hope to see some great websites and phenomenal websites that you're going to create with Next.js.
02:30:17 No websites.
02:30:18 Comprehensive, dedicated web applications, for that matter.
02:30:23 Thank you so much for the kind words.
02:30:26 On the topic of who we are and what we do, if you don't know, I can share maybe a bit more on that.
02:30:34 Um, I think we have it here.
02:30:36 We have tried, we have started doing Next.js a long time ago, ever since 13 or 12, we're in alpha and new features are coming along.
02:30:44 And I've actually created a course on the topic as well.
02:30:48 It's under jsmastery.pro.
02:30:52 right here, we try to make it kind of the only and the best Next.js course out there.
02:30:59 And as with the workshop, we dive deep into some parts and we do it in an example as well.
02:31:06 The premise of the course, and this is not just me selling it, this is me kind of extending the workshop as well and talking about the idea and process
02:31:14 of creation of the course.
02:31:16 The idea was to completely modify your mindset for writing Next.js code.
02:31:24 Because Next 12 and before is completely different from Next 13 and 14. Why?
02:31:32 Because it's not just as writing good old React code, right?
02:31:35 It brought many differences to the way that we write React.
02:31:39 with these hydration errors, the use server, server actions, stale data, data fetching on different parts, edge versus no runtimes,
02:31:48 dynamic imports, right?
02:31:50 You cannot just jump into it like you're using React, right?
02:31:55 That's what we did actually.
02:31:56 I built our entire course platform, our landing pages and everything, and we ended up turning it into a client-side mess.
02:32:04 But now, thankfully, we have learned how to do it.
02:32:07 And if you dedicate this approach, you can have phenomenal performance due to all of the benefits that it provides.
02:32:14 So if you're interested in the course, we dive into deep dive into all of these lectures with great slides, like similar to ones you've seen.
02:32:22 We dive into the build and deploy of a Stack Overflow application, which we're going to build from scratch to be able to internalize those processes.
02:32:30 And then active lessons that allow you to really ensure that you not only follow along, but actually build in practice based off of the tasks that we give you.
02:32:41 For example, creating the filtering or the searching capabilities and so much more.
02:32:46 all while building this Stack Overflow application.
02:32:51 So we wanted to do something that is quite interesting where you have CRUD operations, you have following, liking, commenting,
02:32:59 nested comments, chat GPT, AI-generated answers, you name it, it's there.
02:33:07 Quite a lot of stuff is happening.
02:33:09 But on the other hand, for the longest time, we have been just doing YouTube.
02:33:15 For about five years or even more, I've been producing just free educational content on YouTube.
02:33:22 Let me just exit out of this not to have any audio happening.
02:33:26 Uh, we do it for a long time.
02:33:28 Every two weeks we release one new video and most of the recent ones have been exactly about next 13 and 14. For example,
02:33:36 like building e-commerce applications, um, using server actions.
02:33:41 This is a great video that we have created specifically about server actions.
02:33:45 portfolios, social apps, you name it, it's there.
02:33:49 That's what we have been doing for the past five years.
02:33:53 We dove into Next.js as if server actions were still in alpha, and we tried to go through the trial and error process of figuring it out on our own.
02:34:03 Our Next.js full course is one of the fastest growing Next.js courses on YouTube right now, and feel free to consume it,
02:34:13 but more than that, I want to invite you to use that Discord server that I showed you, the forum, to ask any questions and myself and Sujata will directly
02:34:24 answer you if we can help in any other way.
02:34:29 Recently, we have also started a bootcamp program called the JSM Masterclass Experience where we really try to help people go from junior to mid or senior positions.
02:34:41 I'm not sure where are you right now in your developer journey.
02:34:45 Would you mind letting me know?
02:34:47 You can do, let's say, unemployed, junior, mid, senior.
02:34:52 You can write it down in the comments just to figure out who was listening to this workshop today.
02:35:01 Interesting.
02:35:01 I can see junior, but then I can see a couple of seniors as well, head of engineering as well.
02:35:06 Philippe, that's great.
02:35:08 Okay, mostly senior and mid, which is interesting to hear.
02:35:13 From your perspective, did you know about most of these Next.js things and kind of how did you find them?
02:35:21 Let me ask you this.
02:35:24 How do you think the landscape of web development and React development specifically will change now that Next.js is making all these introductions of
02:35:35 these features and incorporating them on top of React.
02:35:40 If anybody would like to kind of start the conversation and maybe even on your mic, especially seniors, how do you think the landscape of web development
02:35:47 will change?
02:35:48 And are you welcoming these changes with open arms or do you think kind of next year still has a long way to go?
02:35:54 Okay, I can see some people kind of suggesting that to push to newer features, especially when upgrading to React 18, it will be massive.
02:36:03 I only have the fear of being Vercel bound.
02:36:06 That's a really good point that a lot of other people make as well.
02:36:10 Although, you know, That's a good one.
02:36:13 That's a good one, actually.
02:36:14 But yeah, Next.js does allow you to exit out of Versel, but they make it so convenient to stay with Versel that you necessarily don't want to move,
02:36:24 right?
02:36:24 But I do get your concern.
02:36:27 Thank you so much, guys, for being here.
02:36:29 I see a couple of people have to go.
02:36:31 We have hit our time limit as well.
02:36:33 You have been a phenomenal but quiet audience.
02:36:36 I hope you were able to learn a lot and I hope to see you maybe, I don't know, in person next time on Git Nation's conference or one of the conferences
02:36:46 or I see you on the internet.
02:36:47 You can also add me on LinkedIn.
02:36:51 I'm happy to chat and kind of exchange some thoughts as well.
02:36:56 But first of all, I'll see you on Discord in the forum.
02:36:59 We can keep the conversation going on there.
02:37:01 Thank you so much and have a wonderful day.
02:37:05 Bye bye, everybody.