Next.js - the full-stack framework
The previous blog introduced our Next.js Template and discussed why we use it. This blog will cover Next.js' features and full-stack framework utilization.
Read the first part here
Next.js is a framework based on Node.js, which has become a game changer in the web development world. But what makes it so popular? Thanks to its frequency and quality growth, there are plenty of answers to that question. Some of them are file-system-based routing, dynamic routing, great SEO solutions coverage, components optimization, and the two most important ones, which we will dive a little deeper into - Pre-rendering and API routes.
There are three possible ways to pre-render the page with Next.js, and we will explain each one in detail:
Static Site Generation (SSG)
Server-Side Rendering (SSR)
Incremental Static Regeneration (ISR)
SSG - Static Site Generation
Static generation is the default way that Next.js pre-renders pages. That means that HTML is generated at a build time because its content does not change, which means it can be cached by CDN (Content Delivery Network) and served almost instantly. Once exported, it can be compared to the normal React build.
But what if we need to show data from the API?
Well, the solution for that is "getStaticProps"—the built-in function telling Next.js that the page is statically rendered, which means that it won’t re-render until the next build. Whenever a user loads the page, the code inside the getStaticProps function gets executed first and will always return the object. Even if we have dynamic routes (for example, the unique ID of a blog), we can use another function, getStaticPaths, which returns an array of objects containing route parameters. You probably noticed that there is a fallback property we are returning to inside getStaticPaths. So basically, if we set the fallback to false, we tell Next.js that there are no more paths to be fetched besides the ones we already fetched. This is useful for smaller arrays, which you can fetch all at once, but if you have a larger application with lots of different dynamic paths, you want the fallback to be set to true, which will mean that we don’t need to fetch all items at once.
SSR - Server-side rendering
With the function getServerSideProps, Next.js will make a new page for every request when the data changes quickly, making sure that the data is always up-to-date.
While getStaticProps runs at build time, getServerSideProps runs at request time.
Since the page is rendered on the server, the SEO level will be the same as with SSG.
The good thing about SSR is that the website will render faster on the first load, but it has its downside as well—on each request, the user has to wait for the server to generate the page, and sometimes it can take a few seconds. To solve this problem, we can use Cache-Control with the setHeader function that comes inside the "res" property of the getServerSide function. For a better understanding of Cache-Control, check out https://web.dev/stale-while-revalidate/.
ISR - Incremental Static Regeneration
ISR is a hybrid solution for rerendering pages because it allows the regeneration of static pages during the runtime without needing to rebuild the entire site. Using ISR gives a new property to the getStaticProps function in which you inform the page how frequently it should be revalidated.
With v.12.1.0, Next.js introduced an exciting new feature-on-demand ISR. As the name suggests, with revalidate on demand, you decide when you want to revalidate the page, giving you much more control.
But, here is the most exciting part. For implementing on-demand ISR, we have to use Next.js as the backend framework. In the next section, we will cover a few examples (including on-demand ISR) of using Next.js as a backend framework.
Next.js as a backend framework
As one of the main features of Next.js, API routes offer full backend support for your application based on Node.js.
We've already talked about on-demand ISR, but now let's see how to set it up using the Next.js API folder.
Adding a file inside the "pages/api" directory, Next.js will automatically create an endpoint with the name of that file. So if we have revalidate.ts, the endpoint will be http://example.com/api/revalidate.
So, the next thing we need to do is figure out how to set up the backend and frontend logic for revalidating the page on demand.
Here, we are creating the endpoint inside ‘pages/api/revalidate’. First, we check if the user has the authorization to execute a specific function (in this case, revalidate). If everything is valid, we execute res.revalidate with the route we passed inside query params, and return status 200 OK PeopleList.tsx
Now on the frontend, we will fetch that function with our token and the route that we want to revalidate. In this example, we are storing tokens inside browser cookies. Now, with the click of a button, the user can easily revalidate the query whenever they want.
This is a basic solution for writing the backend inside Next.js, so in the following example, step-by-step, we will go through the solution for sending emails, in this case, sending job requests through our form, which we use here at Cinnamon.
1. The first step is to disable the Next.js parser inside the configuration and import two packages-nodemailer and formidable.
2. The second step is to create an asynchronous function and define variables for files and fields in which we will extract the data from the form with the promise.
3. The third step is to parse the data and format files so that we can use them inside the mailOptions object. With the mailOptions object, we define everything about the email. In this case, formData.email is the email address that the user entered in the form, and formFiles is a list of all the files, such as CVs, cover letters, etc.
4. The last step is to make a transporter function from the nodemailer. This function lets the user send us an email with the mailOptions data, and then we send the response email back to the user.
Next.js is a very effective framework that undoubtedly makes a difference. Since we at Cinnamon strive for the best possible solutions to develop web applications, Next.js is a perfect fit for us.
However, today, constantly updated, Next.js has a lot more features to offer, like:
-Image components and image optimization
In the next blog in this series, we will walk you through the layout methods that we use inside our Next.js template, so keep and eye out and subscribe to our newsletter.
Subscribe to our newsletter
We send bi-weekly blogs on design, technology and business topics.