Transcription
Hello everyone, it's Max from Red Group channel, and this is a new format on our channel: a full courses format, but in a shorter version, with cool editing and a cool script. The format will be called Red Essence for now, and we'll see from there. So, this video is very heavy, guys. Videos like this will be released extremely rarely on the channel. But if you want us to shoot the next video and start preparing for it, let's get 2,000 likes, and we'll shoot the next video. And in the comments, suggest ideas for which technologies to shoot this format on. Also, don't forget to subscribe to the channel, and on the screen, you can see a QR code. Subscribe to our channel, there's a lot of exclusive material. In this video, we'll cover when to choose Next.js and when React, new routing and its features. We'll break down useful hooks: `useRouter`, `usePathname`, `useParams`, `useSearchParams`. We'll learn how to work with layouts. I'll show you how to do proper SEO optimization in Next.js applications. We'll analyze different data loading approaches: SSR, SSG, and ISR, and I'll tell you when to choose what. We'll definitely touch upon the comparison of client and server components. We'll also cover middleware and much more.
Chapter One: Basics and Installation
So, let's break down what Next.js is and its advantages. It's a framework for server-side and static rendering of React applications. Now, a bit about the advantages: excellent automatic code splitting, which directly translates to fast loading of your website. Incredibly cool optimized rendering: SSR, SSG, and ISR. And in this video, we'll touch upon this topic. I'll tell you what, when, and where to use, and why it's cool. Very convenient routing, so convenient that even the React Stack Router is trying to integrate it into React. Automatic optimization of images, styles, fonts, scripts, and so on. Incredibly cool application build optimization. The application builds very quickly and shows detailed statistics about each file, each page. This is very convenient for optimizing applications. In this course, we will only focus on the frontend part. We will not be разбирать the server-side part because I sincerely believe that Next.js is number one in the field of frontend frameworks. I don't like approaches where we mix the database into Next.js, mix the backend into Next.js, and so on, when the backend enters the frontend. This is a bad approach. At the start, this approach might seem optimal to you, but as soon as the application expands and scales, your costs will increase, and it's definitely not worth it. Your project will turn into a complete mess. Therefore, in my opinion, try to separate. At the beginning, you can play around, yes, for a small amount of time, but as soon as you create a real, high-quality project, be prepared to separate. Write the backend separately, the frontend separately. Don't mix it all together. And as I believe, Next.js remains the strongest framework in its field. So, now let's move on to project installation. It's all very simple, actually. We type `npx create-next-app`. And in this regard, it's actually better than React. That is, in React, if you install through Create React App, it's installed through Webpack, and all of this is very long, slow, and so on. Next.js has modified this a bit, and now it's much more convenient in Next.js.
And do you know who else is number one? Cloud.ru. They hold leading positions in cloud services and artificial intelligence. The company offers a wide range of cloud services of different levels. Cloud.ru has modern supercomputers and reliable cloud services that guarantee uninterrupted operation and protection of your data. Today I will tell you about the Evol free service: a free virtual machine with a given configuration, as well as 5 GB of standard storage and 100,000 GET/HEAD operations forever. Also, a convenient service for developing containerized applications and a private image repository. And also, what is relevant for our audience, soon there will be a service for working with PostgreSQL. Create, test, and develop applications for free. For our viewers, Cloud.ru has provided 4,000 bonuses for registration, Sber ID, or card linking. This offer is only for new users. One bonus equals 1 ruble. Public cloud is paid, but you can easily pay for it using bonuses. Let's show you how it works with an example. So, on the promotion page, click "Connect." Choose a linking method: either Sber ID or standard registration. Then you will need to link a card. Enter your phone number, then enter your email, then enter your first name, last name, and password. Registration is successfully completed. Now let's log in. After successful login, as we can see, we get 4,000 bonuses for testing. But first, we need to add a card. On this page, quickly add a card. Well, and as you can see, the bonuses have been credited: 4,000 bonuses. I'll leave the link in the description. Get your bonus right now. Let's do `npx create-next-app` and type the name of your application. By the way, guys, I'll drop a link in the description to download this source code. If there's anything useful there, I don't know how useful it will be yet. Click Enter. Let's use TypeScript or not? I suggest using it because TypeScript is already a must-have for Next.js applications. Click Yes. ESLint or not? I'll do it without it because ESLint is more for teams. Let's use it so that writing styles is faster. Source directory? Yes, we'll use it too. It will be simpler to implement the folder structure with it. Routing, of course, let's say Yes, definitely. And aliases. They will be by default. That is, when you write an import instead of writing `../` and the depth can be infinite, and if you move files between folders, conditionally, your paths won't change. Although in some IDEs it changes. Aliases allow you to keep it in place even when moving. You change the alias in one place, for example, `layout`, and it will always be used identically everywhere. Here, it suggests integrating it anyway. It just offers you a variation. By default, it will be in this format. You can press No, this can be edited in the future in `tsconfig.json` without problems. I'll say No, the default option suits me completely. Click No. It shows us what will be installed. We will use npm again. In this video, I will specifically use other package managers, neither yarn nor pnpm, because I know most of you use the classic npm package manager. So, to have a similar picture on your computer, conditionally, we will use the usual npm to lower this entry barrier. So, what dependencies are being installed? These are standard packages: React, ReactDOM, and Next.js, obviously. And dev dependencies are default dependencies in development mode: TypeScript, classic React types, ReactDOM types for these libraries, PostCSS, and Tailwind CSS for compiling Tailwind CSS code and, accordingly, for Tailwind itself. Let's go into our folder. It's all very simple. Type the command `code` if you have VS Code. Again, you'll need to install something through the terminal for this to work. Let's type `code` and specify the name of our folder. The folder will be named after the project name, i.e., `Essence-Next`. Click Enter. Here's our project successfully opened.
Chapter Two: Working with Structure and Components
So, guys, let's break down the basic structure of any Next.js application that will be available to you immediately after installation or initialization. Let's look at the `node_modules` folder. I will analyze all folders, even though you should already know something at this level because this level is more for junior and above. But nevertheless, if you don't know something, if you have any knowledge gaps, I will explain it from scratch. So, the `node_modules` folder is the folder where all libraries/dependencies and dev dependencies and regular dependencies are stored. They are stored here. You can also see the list of files in `package.json`. We'll touch on this later. It contains the entire list of dependencies you have in your project. So, keep in mind when I say dependency, I mean libraries. The `public` folder is a static folder. That is, files that you put here, images, it doesn't matter what you put here, your path will be completely static. That is, for example, `localhost:3000/image.svg`, `image.svg`. So, the path will be as direct as possible. So, put all static assets in this folder. The `src` folder. We'll touch on it a bit later. It's the most important, the most fundamental. Let's analyze the root files. That is, the file located in the root of your application. `.gitignore` is for specifying what to ignore. `next-env.d.ts` is a TypeScript declaration file, specifically from Next.js, which allows you to type your project and add some important types. `next.config.js` is the configuration file for your Next.js application. We'll get back to it a bit later. `package-lock.json` is the same as `package.json`, only it contains the specific versions of certain libraries, and it's needed, for example, if you have two versions of a project, one locally and one in production. You can easily transfer it, and the version will match completely. `postcss.config.js` is for compiling our Tailwind CSS. `tsconfig.json` is the configuration for TypeScript. The `src` folder is the main folder where all the main files will be located. All our main routing will be located in the `app` folder.
So, guys, before we go further, let's run our application. Open the terminal, type the command `npm run dev`, and run our application. We've launched it. Here's our address. Let's try to open it in the browser. Let's close the terminal immediately. As we can see, our application has loaded successfully and is fully working.
So, guys, a quick explanation about the `app` folder. See, we need it to correctly organize routing in a Next.js application. What can be the routing options? Look, here's some domain, right? For example, `domain.com`. For example, the routing variation can be as follows: `products` - these are our products. It can be the same, but for example, `tv`, for example, some TV, and so on. There are many address variations. Let's implement this now in the frontend itself. How is it done in Next.js? Look, right-click, "New Folder," and create a folder. We'll call it `products`. Thus, we will already have the `/products` address, but it won't open yet. It's important that in every folder where you want it to be displayed at this URL, there must be a `page.tsx` file. As here, let's create a simple function. Export is mandatory. It must be a default export. Here, let's write something. Save. Look in our browser. Here, please, "products" opened successfully. And on the same principle, we can specify, for example, inside products, "New Folder," then `tv`, for example, and so on. And also place a `page` folder in it. Everything will work the same way. But here you saw one nuance, right? Max, how do you specify `tv` if we can have both `tv` and, say, a microwave, I don't know, and a microphone, and anything else? We need slugs, right? So, specify here. Click Enter. And square brackets allow us to specify a specific slug that we can potentially get using hooks, which we'll cover later in this video. Thus, here can be both `tv` and a slug, and anything else. And you can get data based on what the user entered or where you redirected them. The same applies to other pages. You can make this nesting infinite, to the point that instead of `products` here, you'll have a product category, a category slug, for example. And so, first, you have an unclear category, for example, `tv`, and then the TV itself, LG, or maybe not `tv` but a microwave, right? For example, and there's Samsung, for example, that's another Samsung. You understand the point, right? Also, there are nuances. Some people ask, Max, what do the parentheses mean? There are cases when you create a new folder, it will be called `student`. This is a space for the student, their personal account. But what if we also have an admin panel, `admin`, and there's also `page.tsx`? What if we want to create one common layout for them because it's both a personal account and a personal account? The difference is only in functionality. So, to combine them into one scope, and moreover, to allow this scope only for authorized users, we right-click, "New Folder," and specify that it will be `dashboard`. And then, yes, if you specify parentheses, this address will not be counted in the address bar. That is, you won't have `/dashboard` because you specified `dashboard` in parentheses, so it won't be counted. And then place `admin` here and `student` here. That's it. And here, at this level, you can create layouts and work with them. This is how routing works in the new Next.js.
Let's immediately cover the `Link` component, guys. This is how we work with routing now. See, there's a link, it's a regular link that Next.js gave us after installation. Let's change it to our unique link component that will allow us to redirect. We replace it with `Link`. We import it here too. We replace it with `next/link`. We close the tag, and we don't change anything else. The `target` attribute is also there in `Link`, so you can leave it. And `href` too. Leave it if your address is external. But an external address is absolutely not interesting to us. So, we remove this. We remove this. Our address will be internal. So, we'll do `/` and, for example, the same `products`, and that's enough. Save. Go to the browser, guys. Click on the logo. Here's the logo by Vercel, and we are redirected to the `products` page. As you can see, this is how it all works without reloading, absolutely.
Now, guys, let's move on to analyzing layouts. Why do we need layouts in the frontend, and specifically in Next.js, and why do we use them at all? Layouts allow us to create a wrapper. The functionality we can implement is absolutely limitless. We can simply change the visual wrapper, for example, for all pages that will be wrapped by this wrapper. All folders that will be located here, because this is considered the root wrapper, all other pages will be wrapped by it automatically. So, conditionally, we can change some titles, descriptions for SEO. We can also, for example, change the visual component, add a header everywhere, add a footer everywhere, and so on. So, everything we want to deliver to a wide audience, that's what layouts are for. Conditionally, a layout can be, as I said before, in routing, as a root layout, and it can also be at the level of other folders that you create. You created a folder, for example, and inside it, there can be another layout specifically for this folder. This is what layouts are for. Now let's analyze the correct structure of components. The correct structure of components. I'll show you later. Don't switch. I'll show you later. I'll open a large project and show you how it's implemented there. Briefly, yes, we have the `app` folder. We do routing there. I'll explain my methodology. Let's write, for example, a new folder there, `products`, and so on. Products. In principle, you can do `page.tsx`. You can do a client component that will be related to this, for example, `Product.tsx`, and use it even in `page`, and so on. Because `page` most often handles the server-side part, this will already be a client component to which the server will send data. As for other data, other components, other utilities, and so on, I move them outside the `app` folder. For me, the `app` folder is purely routing. I have a `src` folder. Right-click and continue writing code there. For example, here will be utilities, some `utils`, some will be just `components`, and inside them will be the UI itself, and so on. This is how, in my opinion, the correct component structure is created. That is, when everything is clearly divided by folders.
Now let's analyze the structure of a specific real project that we did on the channel. A large project. It will be clearer to you there, how it's used in real practice. By the way, you can see the project on the channel called "On-Demand Planner." Here you can see the `app` folder. Everything related to working with pages is there. And all folders are inside the `app` folder. Purely routing. This is, you see, I wrapped it, purely personal account. So, authorization is separate. You see, authorization is there, and these are standard files that we've already seen. Then, next to it, `components`, `UI`, `layout`, `config`, `page`, `URL`. Yes, here are regular pages, constants, hooks, services, and so on, and types, directly. And here is the `middleware.ts` file, which we will cover in this video. This is the structure of full-fledged real projects.
Chapter Three: Styling and Visual Design
So, how can we write styles in our application? The most basic, the most correct way is to import modular styles. Expand the component, and for example, want to color a div. Type `className`. And what modular styles allow us to do is generate unique classes for a specific page, thus these styles will be unique only to this page. Let's type `products`. Now, right-click, "New File," `products.module.css`. We've created the file. Now we can describe `.products` classes. You can write minimalistic classes. You can forget about BEM, it's not needed here. And you can write any style. `background-color: aqua;`. The color will be aqua. Save. Go to the browser. Look, the aqua color has appeared. This is how easily styles are written. You can also add SCSS here instead of CSS. It's very easy to install. Open the terminal, type `npm install -D sass`. Close the terminal. Just rename to `.scss` and reload the compiler. Here, change to `.css` in the import as well. As you can see, `font-size: 30px;`. In the browser, everything works the same way.
So, now let's load fonts. Fonts are also one of the features of Next.js. It's very convenient. It's done here. As you can see, in the example that is given after installation, there is already a specific font, Inter, which is very convenient. You don't need to download anything. You don't need to add anything to the project. Everything can be taken directly from Google Fonts. Specify the desired font. Let's change the font to "Metal," let's put it, why not? You can change it here. You can not change it here. This is just a regular variable. Change `font-weight` here to `400` and save. Look at the browser. As you can see, the font has been applied. This is how quickly you can apply fonts to any application. Don't forget to specify the connection here via `className`.
Now, the 404 page. We need to create `not-found.tsx` in the `app` directory, directly in the root directory. And now, go to the browser, type any URL, and get a 404 error. This is how easily it's written. Just be careful, we write not `404.tsx` but `not-found.tsx`.
Now let's cover how to insert images in Next.js using their unique Image component. Open any file. Create a component from `next/image` here. Make a `source` directly, and specify the path to your image. You can use import or a regular path. If it's in the `public` folder, statically located. Remember, we had an interesting file in static: `next.svg`. Let's make it `next.svg` because it's in the root. And specify important parameters here: `alt`, first of all. Secondly, you can specify the size, approximately 50 by 200. And so that, guys, we can see it, let's change the background color. Let it be `gray`. Save. As you can see, our logo has appeared.
Chapter Four: Useful Next.js Hooks
The first hook is `useRouter`. Be careful when you use `useRouter`. Import it specifically from `next/navigation`. If you are using the `app` directory, otherwise it won't work. And as you can see, it tells you that it will only be used in a `useClient` component. We'll cover what `useClient` is later in the video. Let's temporarily, in short, always use `useClient` in your code. This is mandatory. In short, it simply turns a file into a client component. And let's see what we have here. We can get `back` for navigation. Back arrow, conditionally, in the browser. `forward`, forward. `refresh` for reloading some data. Honestly, I've never used it. `push` is a very frequently used thing so that you can redirect a person to a page. Specify, for example, `push('/products')`, and it redirects them there. But there's a more interesting function: `replace`. `replace` allows you to do the same as `push`, only it clears the history. Thus, if you go to this page, you cannot click the back arrow in the browser. This is a very useful thing when you redirect after authorization. Thus, a person cannot go back, and no error will occur because the person simply cannot go back. And there's also `refresh` for reloading the current page. We often use two things: `push` and `replace`.
Let's cover the next hook: `usePathname`. It returns not an object, but a single variable. It simply shows the current address of your page, where you are. The current path of your page. Relevant when using, for example, when you need to show an active element in the menu, or I don't know, make a check, if the page is such and such, we do such and such an action, conditionally. But again, I recommend doing all sorts of checks on the server-side, not in Next.js, using interesting functions that we'll cover later in this video.
So, the `useSearchParams` hook. `useSearchParams` works only for query requests. And if you want, as I said, to get the current slug from the folder if it's implemented through square brackets, then for this, there's simply `useParams`. Let's take `params` and see what it has. It has `entries`, `forEach`, `get`, `getAll`, `has`, and so on. In it, you can specify what parameters you have. For example, I do it like this. Specify TypeScript. For example, I have a `slug` parameter, which is a string. Now I do `params.slug`. This is my current string parameter, directly. This is how it all works. You can see examples of other hooks in real practice on our educational platform, HTML Lessons. There, in the intensives, in real practice, you will cover all the most useful hooks. We will cover React and Next.js intensives, a total of seven of them, of different levels. Including the cherry on top: the intensive "Day 0" for beginners and also suitable for advanced levels, where we developed a banking application on pure JavaScript. There is also an online calculator on Next.js that we made, and many other projects of different levels. The most important thing is that everything is under a general subscription. You pay once and get access to the entire platform. There is also support in the VIP chat and over 80 ready-made project repositories. I'll leave the link in the description. There, choose the tariff of our subscription that suits you. And perhaps, by the time of this video, guys, the long-awaited "Dark Side" has been released, a global update to our platform, which was developed for one and a half years, or you can say, very long. So, check the description to see if it has been released yet. So, guys, I recommend our platform to everyone. Jump in, buy a subscription, and learn programming almost for free. The link is in the description.
Chapter Five: Data and Server Components
Let's analyze and compare server and client components and understand what is used for what and why you cannot use only client or only server components. Let's first move on to the advantages of server components. These are data loading on the server, i.e., SSR, ISR, SSG, and so on. The next advantage is access to backend utilities, access to the backend in general, directly. This is a very cool thing. I myself recently started using it in projects to its full potential. Yes, it's cool in the sense that it's protected. In this regard, I really like Next.js. There are very important things that you would want to perform only on the server, for security reasons, because everything that is done on the client can be easily accessed using the browser. That is, any attacker can get access. According to the documentation, there is also the next advantage. I've actually included the previous advantage. Yes, this is access to data from the perspective of security: access tokens, API keys, and so on. Then, another cool advantage is to leave heavy content on the server, so that the server deals with it, and on the client, that is, in the browser, bring out everything very light, reducing the amount of JavaScript code in the browser, thus the site loading will be faster. Now let's move on directly to the client-side. Well, the first is the use of states and various effects when loading, when mounting a component, when unmounting, various hooks like `useState`, `useRef`, `useEffect`, and so on. The classic of the genre, I think. Also, direct use of various event handlers: `onClick`, `onChange`, and so on. Then, the use of browser APIs. Use of custom...
Hooks that depend specifically on the browser, meaning tracking the state of something, and so on. Everything that depends on the browser, you can use. And of course, React class components. Well, we'll put a star there because few people use class components. But class components don't work on the server, it's important to understand. So, let's briefly break down what to use for what, and how I use all of this in my practice, in my large projects, including the commercial project that you will all soon see on your screens, Darkside. And what I have ultimately learned for myself after, well, how many years have I been in Next.js, about five years. All the pluses that I have written will follow precisely from them. Accordingly, if you use various libraries like, I don't know, a text editor, for example, Codi, MSE, Google Maps, Yandex Maps, anything, it's more logical to wrap it all in a client component and use it calmly. It won't work on your server. As for server-side stories, it is advisable to load data with one, but not through SSR, but through ESR or SSG, that is, either through pure static without data updates, or static with data updates. In this way, the costs for your server when you deploy your application in the future will be scalable, the costs will be minimal because you are working with static data, it updates, but overall it is static. If you do as, again, most Western bloggers and not only do, that is, they use SSR purely SSR everywhere, when one request to the server equals one response. If we don't consider server development now, if we don't consider server caching now, but take a regular classic server, your server costs will be very high. I encountered this in my time when the site had about 500 people, and the server costs were enormous. Then I understood why this was happening, so keep that in mind. SSR is used extremely, extremely cautiously. I also recommend using all these stories only for SEO. That is, why would you use SSG and ESR in a personal account? Why? If, in my opinion, it's better to load on the client, you will have convenient access to pagination, to passing various parameters, meaning you can use the same React Query API and so on, and it's much more convenient than if you were to load the server first, then load all this into your React Query, well, it's an unnecessary layer in my opinion, and it's, well, it's useless in my opinion. And also, working with authorization is more convenient in the client-side. I would recommend using it only on public pages, on your blog, on the main page of the site, where you need SEO optimization so that everything loads quickly, you can use it there where authorization is not required. If to put it briefly. And of course, I would also use server components where a certain security is needed, that is, where you need to check authorization and it's important for it to happen before the page loads, so that when a person loads the page, they don't know if it's being checked or not, and the correct template is immediately shown to them, then this is ideal. You can even check your JWT token, you can load some data, you can use images, in short, you need a certain balance. In this video, I will try to reveal the topic, but for a more in-depth understanding, it's better to watch the "Large Projects" section on the channel, where we have already done all this in practice, or on the intensive course website, it will be clearer. So, guys, how do we indicate whether it will be a server component or a client component? All components are server components by default, so writing "use server" is not necessary. But when the "use server" directive is written, what is it for? It's for server actions, in short, these are functions that only happen on the server. For example, we have some function. Let's show an example: export const getToken, for example, right? We get some conditional token. We can easily get it here through console.log, for example, for example, process from the .env file without any problems. We can extract it, right? process.env, for example, token. I'm just giving an example. And we write "use server" here. This makes it a server action, only on the server. Yes, many might think now, Max, but if we add it to .env, doesn't it show up on the client side? No, it doesn't show up. Look, if you just create a regular variable in .env like this, and at the same time don't specify it in the next.config, but just leave it in .env. And at the same time, if you don't write "public" at the beginning, I don't remember, "Next Public", yes, according to the documentation, you can check. Next, I think, yes, it's signed like this. In that case, if you just create a regular variable in the .env file, it will only be available on the server, it won't load on the client because you haven't enabled it anywhere. But as soon as you give it the name "Next Public" or add it in next.config, it becomes available on the client as well. This is no longer safe, be careful with this. And this is what server actions are for. And you can also easily use the "headers" function here, which is wonderful, it gives us server headers. We'll deal with this later when we analyze middleware directly. So, this is a very convenient topic. Well, again, without overdoing it. You don't need to turn Next.js into Laravel. You don't need to do, you know, like we had in Laravel when you send a form directly to the server. You don't need to do that. For this, we have the frontend part that validates all of this, sends it to the server, and so on. This is a more correct approach. It's important, right? We are writing "use client" here now, and then it only works on the client. Let's show an example. Let's open "page". This is a pure server-side story. It will always be server-side. This root file, routing. And I'll write "page" here, for example. Let's save. As we can see, it's visible in the terminal. "Page" was output, and it was output only in the terminal because it's executed on the server, i.e., before loading in the browser. We will analyze many useful things here, including, as I said, all functions will be analyzed in middleware. Everything happens on the server there too. In particular, right here, I suggest analyzing data loading, the very one. We have three options: SSR, ESR, and the last one is SSG. If we expand it: Server-Side Rendering, Incremental Static Regeneration, and Server Static Generation. I hope I translated correctly. In short, the meaning is clear: static, static that re-renders. I've already told you about this. Well, we're moving on to the request itself. Let's make a regular export here. Or rather, without export, const fetchData. This will be some conditional request. It is, of course, asynchronous. And everything we do, we execute it. Copilot recommends it. Let's leave it. Well, just a basic test request through a regular fetch. Here our request is executed, and it's asynchronous. Therefore, we can safely make a server component asynchronous and execute fetchData here. That is, const data = await fetchData. We got the data. And the beauty of the server is that you can check right here if the data didn't arrive, for example, we return the "notfound" page through the directive like this. Yes, you can do that. Or, it seems there is "notfound" for us. Yes, there is even "notfound". You can even return it like this. And if there is, we pass the data to, for example, our component. Well, I won't do it in TS, it will complain. In short, we pass to the component. What you see on your screen now is the usual classic approach called SSR, the usual server approach, which again, everyone recommends, but it's not optimized. I repeat, with this approach, one user equals one response from the server. This exchange is maximally unoptimized, and you can test it yourself. As soon as you have at least 500 visitors on your site, 1000 visitors, you will have huge server costs. Well, not huge, they won't be super cosmic, but your server will constantly require tariff increases because there are not enough resources because it's not optimized. To make it optimized, you need to do one of two things: either convert everything to full static, how to do that? Let's analyze. To indicate that this is static, we put it with a comma, we specify "options" that we have. It seems like this is a regular classic fetch, right? We have "next" further, but there is something interesting. There is, first of all, "next.config". There is "cache". Yes, there is also "cache". Let's introduce "cache", and what variations do we have in "cache"? Look, there are defaults, there is "force-cache". This is exactly only static. There is "no-cache", "no-store", "only-if-cached", and "reload". So, look, if we specify "no-cache", in this case it will be SSR. I understand that this is the default value. Perhaps, guys, I will be wrong in some moments, and I will correct myself in the pinned comment or in Telegram after reading your comments. I've made some corrections below. So, Telegram, subscribers, QR code on the screen, you see. In every full course, I make some mistakes. This is normal, human factor. And if I'm wrong somewhere, I admit it and write about it in Telegram because there are moments when Next.js updates very often, and there can be moments that I, let's say, took from a previous version, conditionally. I mean, from a previous, not full version, but they are already, for example, different. So, we specify "force-cache". With this approach, what we have written is SSG, that is, pure static. Data is loaded only once when your project is built. When you type "npm run build" in the console, the project is built, and you will see everything. We can't build it now because it's a fake address. In general, you can test it yourself. If we are talking about ESR, that is, Incremental Static Regeneration, the case when you have static data, and at the same time it re-renders. So, for example, you changed the product name, changed its price, and so on. Now, of course, this is a lot. In fact, I usually set 200 milliseconds, regardless of how it comes out, so that the site updates quickly. But this is regarding fetch. We have analyzed this. If we take an example, many ask, Max, so what, should I use fetch all the time? I will answer: if you use REST API, not GraphQL, but REST API, if you don't know what GraphQL is, you don't need it. Then use fetch. It helps you do everything and so on. And as I said, if you use my approach, when authorization is primarily done on the client side, on the server we can only check it somehow, then you don't need any interceptors and so on. On the server, they work terribly. Therefore, I recommend using regular fetch. Fortunately, you don't need authorization here. Or wrap it with your scope, add tokens and so on. If you use, for example, as I do in my projects, a higher level, use GraphQL Apollo, or for some reason you decided to use Axios, anything, Next.js has provided for this, and they cache all of this automatically. That is, you don't need to write this command. You only need to write "revalidate" if you need it. That is, you write a variable: export const revalidate, and also set it to, say, 3600, which is one hour. So, with this approach, data will also be re-rendered every hour. And you don't need to write this. It happens automatically. That is, Next.js caches the data itself. But again, keep in mind that fetch, when used, has more functions. After all, they focused on fetch. Chapter 6: SEO Optimization. So, guys, if we talk about SEO optimization, we have already covered a huge amount of information, and probably basic SEO has been covered regarding data loading. With these approaches that I have indicated, SSR, SSG, ESR, data will be loaded here, and search engines will see it without problems. What should we do with other SEO optimizations, headings, and so on? Let's analyze interesting features. First of all, we have this wonderful object, and this is a real innovation in the new Next.js, this was not there before, it's really convenient. You just create a constant "metadata", specify "title", this is the heading. And let's analyze the most non-obvious metadata options that can be. Well, first of all, it's "application-name". That is, if you are making, for example, a PWA web application, you need to specify this. "icons" are optional, "author" is optional, "category" is optional, "creator" is optional. "description" is mandatory. Then "format-detection" is a useful line when you have some number, for example, sometimes iPhone thinks it's a phone number, possibly just digits. "icons" are very important here. "icons" are specified, and "apple-touch-icon", "manifest" is a very important file. If you are using, again, making a PWA, in our reality, in the reality of sanctions, this is relevant because many, as you know, banks, for example, build web applications. And the manifest file is mandatory, otherwise your site will not be identified as a PWA. So, keep this in mind, it needs to be specified. "open graph" is a very important setting. This is for social networks. When you repost your site, this is specified. "robots.txt" is a very important setting. If you want to close a page for SEO so that it's not available in search, you specify the second line: "index: false, follow: false". And "verification" is also a cool feature. Before, we had to manually specify all of this. Now you just specify the key here, and Google, Yandex, anything is supported, and you can easily verify. There is no "title" in the general sense. It always changes depending on the page. For this, there is. I won't analyze this function for long, it's very simple, there's not much to analyze. "generateMetadata" function. Let's immediately take the example I already had. So, we take an asynchronous function "generateMetadata". And it allows you to get parameters. Remember we analyzed square brackets in "app" for specifying typing, certain data you get, and return "title". That's all. Here you can return not only "title", you can return "open graph" as well, without any problems. That is, in this way, you add dynamism. Here we wrote static, here you can add dynamism, exclusively for a specific product. This is a very cool topic. I've commented it out so you can use it. Chapter 7: Extended Configuration and Optimization. Let's create a "middleware" file. Middleware is located in our "source" root folder, "middleware.ts". So, let's analyze what a basic configuration of a middleware file is. It's a regular function that triggers under a certain condition. Conditions are specified in the config area, in the "matcher" area. And you specify under what condition this page works. You can specify here, for example, in this way, you can take an array, anything here is specified. For example, "/about", "/some/path", conditionally. And on these pages, that is, on any page of the cabinet, on any page, our function triggers. What is this for? Well, the most common case where this is used is authorization. That is, when you need to manage roles specifically, close a specific page for a specific role. That is, the cabinet is accessible only to those who are registered. The admin panel is accessible to those who have admin access. How to handle all of this is very simple. You write: const pathname = determine the current path where you are, because it triggers under different conditions. So, request.url. And basically, here is your URL. Yes, then you can conditionally specify that, for example, "includes". For example, you can make the most basic example, I don't know, const isAbout. Again, this is not the topic of this video. I'm showing everything very quickly right now. I'm saying, if this is a page, for example, then we check. For example, I don't know, if our user, for example, if he is, we let him through using the command "return NextResponse.next()", that is, we let him through. Everything, he can go freely. If not, then we send him to the main page. Well, this is the most basic, childish example, guys. The point is not this. The point is that I promised to show you the functions that work here. That is, you can write anything here. Well, now, again, I repeat, for example, in the master class on authorization, which was not long ago, we did, or on the intensive course website, conditionally, we did it so that you check a specific role here and give him access. If it's an admin panel, check it, give access. If not, you can also do complex authorization here. You can also check data by token. That is, well, you can do a lot of things. This is not the topic of this video. This is a very advanced topic, it's not relevant here. Now, what do we have here? "cookies" - this is access to all our cookies. You can specify "get" here, get a specific cookie, for example, "token". Everything, we got a specific cookie, a server-side cookie, we can get it. This is uniqueness. That is, we can get server-side cookies that are not in the browser. This is very convenient. Or you can check refresh tokens, well, this is again to your taste. Besides cookies, there are also "headers". "headers" can be taken from "request.headers", basically, yes. Or you can use the regular "headers" function. It gives us the ability to delete some headers or get them and so on. And there is also a classic redirect. But again, there is no point in it because there is a native redirect from "request" directly from "NextResponse" or from "request". If we summarize, middleware is a very convenient functionality for doing advanced things on your site, for processing everything on the server in advance that you don't want to process on the client, closing access to a page, giving access to a page, and so on. I highly recommend middleware. It's one of the best things that Next.js could have invented. Now let's move on to the "next.config.js" file. Here, the config settings are made. Which ones? Let's analyze the most popular and very important settings. "images" can sometimes be a useful thing, but again, over time I started using "public", as I said, "Next Public", it's called "Next Public". When you just add "Next Public" to the .env variable at the beginning, and everything works for you. So, I don't see the point in this anymore. Then "eslint" sometimes is also experimental. Let's get to it in a couple of minutes. Among the interesting ones, we also have "i18n" for integration with the localization of your site. I wanted to add localization to this video, guys, but honestly, it didn't fit in terms of time. It wasn't in the script. It wasn't in terms of time. This is also a useful thing. You can specify it. This way, for example, an attacker won't know what your site is written on. But this is a childish story. "redirects", "rewrites", "rewrites" are a very useful thing. For example, if you have some path that you want to rewrite, you have a backend, conditionally, say, "api.domain.com", for example. You can rewrite it to "domain.com" without any problems. That is, from one address to another, it can do it easily. Also, if you use images from a third-party resource, it's important to specify the domain, otherwise it won't work. And also, Webpack settings. Sometimes you need to fine-tune Webpack. You can configure them here easily. All settings are present. And also, here in this config, various wrappers for other useful dependencies are made. So, I promised you to show "experimental". Guys, I also wanted to remove it, but then I thought, I'll leave it after all. It's a very useful thing. Recently, I also got it for site optimization. There is a function, it's in experimental mode, it's called "optimizePackage". And here you specify in an array the packages that you want to optimize. For example, "Material UI", you have it in your project. So, it optimizes packages that are inside other packages, meaning it reduces the number of libraries, reduces the number of modules. When you build your project, it reduces. If we open the terminal now, well, I've built a page with 500 modules. This is super small. When it comes to large projects, this really helps. And when you have 3-4 thousand modules, this thing can reduce, say, 500 thousand modules. And your site will work much faster. In my time, with the help of this thing, a subscriber told me, I significantly accelerated my site. I just didn't know such a thing existed. It's very useful. Chapter 8: Advanced Functions. So, let's analyze MDX and how to create fast static pages using Markdown. We all know that there are Markdown files with a .md extension, regular static. But what if I tell you that at one time, GSX and Markdown were combined, and MDX was created? Few people talk about it, but for static content, it's very useful. How is it done? Routing is absolutely the same. You put any folder, write "page", but now not ".md", but ".mdx". It's important that all of this works. Install the extension in VS Code for MDX. Your syntax will be highlighted. The second setting is "extension". Now we have both JS and JSX, and we also add MDX. Let's save. Let's immediately restart our application. Immediately, I'll insert the code. The trick is that you can write Markdown and at the same time import components, meaning write pure JavaScript code. This is totally cool. If you have some static pages on the site, for example, an "about" page, and so on, it will load lightning fast. I'll remove the import for now, we have nothing to import. I'll leave just Markdown. This is a heading. This is bold. This is italic. This is just a regular list. So, how do we install MDX in our project? Look, guys, first, install the VS Code extension for MDX. Then you will need to create an "MDXComponent.tsx" file in the root with the following content in the "source" folder, definitely. And in next.config, first install dependencies, and after that, import "createMDX", call it, and wrap our application. And don't forget to specify "pageExtensions: ['mdx']" here. After this, MDX will work successfully. Let's look in the browser. Here is our Markdown working successfully. So, this is a very simple way if you like Markdown to create static pages in your project. Imports also work here easily. There is documentation for this. And all JavaScript code. Now let's deal with building our project and analyze the build logs. For building, we type "npm run build". Let's run it. Let's wait for some time. We have "next" version 14.2. I don't know when you're watching the video, what version you have. I have an error because I have Node.js installed absolutely fresh, and unfortunately, it's not adapted yet. So, let's look. Let's analyze what we have. We have only static data, unfortunately, because I removed data loading from everywhere. We only have static data. Let's analyze what we have at the moment anyway. First of all, everything is compiled. The builds were successful. Very convenient build. That is, you can run this build before production using CI/CD easily. So, we have generated seven pages, and everything is optimized. The main page is 11 KB. First slot is 98. If something is red, it means you need to do something with it. So, this is an overload. It's static. But we have everything completely working statically, and all the script files that are loaded. Then middleware takes 26 KB. Here it is. This is a separate function. And here, most likely, in your project, I currently only have static icons. If you have other icons, they will be displayed here. You will also have SSR shown here. Server rendering will also be shown. You will be able to track all of this. So, keep this in mind. It's very important to track the status of your pages. I recommend that you have static or incremental static regeneration. Server pages, I don't recommend, or extremely rarely. This is regarding building the project. Now your project is built, and you can easily run it using the "npm run start" command, and it will work a million times faster. Let's reload the site. It opens lightning fast. I don't even have time to do anything, it opens lightning fast. Conclusion and Best Practices. So, when should you use Next.js? Let's analyze, guys, in the finale of our video. Next.js should be used in almost all projects, in my opinion. Because it's just the same React, only it gives you more tools and possibilities. And if you are ready to learn something new, then Next.js is ideal for you. The other question is, look at my previous video on the channel, in which direction Next.js is moving. This is already a secondary question, let's say. It's clear that for now there are no good alternatives. Well, as an alternative, you can use regular React. But then you will lose all the interesting things we talked about at the beginning of the video. Next, regarding the important understanding of separating the client and server parts, I already talked about it in the previous video on the channel, and we touched upon this topic in this video. Just know that Next.js was initially a frontend framework. And you shouldn't put backend into it. I'm not talking about the fact that we use server features. These are very pleasant things, very useful things. I'm talking about when they take Prisma, a database, and pour it directly into your application. Don't do that with Next.js, please. Separate them. You might not care about this at the start when you're making an MVP, let's say, a quick application. Just release it. But think about the future. What will happen to your project later when it has 1000 users, 2000 users, 3000 users? When the functionality expands, what will happen then when your backend is not separated from the frontend? It will be a complete mess. So, don't fall for this trick, guys. I understand that it's convenient to do everything in one place, 100%. But think about the future. Think about the future, and then it will be bad. Then it will be difficult to get out of it and separate the backend and frontend. It's better to write them separately from the start. This is my main message to you. Write in the comments, put likes. Let's get 2000 likes, and we'll make the next format, in which, that is, we'll make the next video, the next topic in the same format, where I will take into account all your comments. So, write feedback in the comments. How did you like this format? Did you like it or not? Because I tried to fit into a short timeframe, but the topic is very deep, and we haven't covered everything I planned to cover. So, write in the comments how you liked this rubric, and maybe what advice you can give me, where I can shorten it even more, and what can be improved to make the video more watchable, higher quality. I always listen to the feedback of our regular viewers, and my team and I will change it so that it's as comfortable as possible for you to watch and reach the widest possible audience. All useful links are in the description. Telegram is on the screen. Scan the QR code, go there. All exclusive content is located there. And there I will also post my exclusive post about what I might have missed in this video and what should be considered. And there, most likely, I will also post the source code of this project. That's all, guys. It was Max. Thanks for watching, guys. Everyone, bye. Guys, just a minute of your time. I'll tell you about our new master class: "Implementation of Payments from A to Z". The master class will take place on April 20th at 10:00 AM Moscow time. But recordings and source codes will remain forever. That is, if you purchase the master class after it takes place, you will still have access to all recordings and source codes. The recording will also have timestamps. In this master class, we will cover the implementation of payments from beginner to advanced level. There will be two full-stack projects. For beginners, there will be a full-stack: frontend from React, backend from Node.js + Express. For advanced level, there will be frontend on Next.js, backend on Nest.js. We will also learn to work with webhooks, learn to work with auto-debiting at an advanced level, like in full-fledged SaaS applications and services. And a small block.