Next.js is an open-source ReactJS framework written in JavaScript by Zeit and further by Vercel and the community. I came to know about Next.js after struggling with SEO for my react project built upon React.js. And I just started learning Next.js from their official docs. And I really liked the idea. It solves the exact limitations that react has and developers try many things to overcome them. Next.js has done this very beautifully. Here in this article, I will explain to you where Next.js is suitable and where unsuitable. And there's much more, so let's get started.
Related Article: Why you should learn TypeScript and ditch JavaScript? TypeScript vs JavaScript
1. Limitations of ReactJS: Need for more Speed
I'm developing stuff in ReactJS since mid of 2018, and it has become my favorite. Along with time, ReactJS has introduced various features that made me stick to it. ReactJS is an open-source JavaScript library, started by Facebook and maintained by Facebook and the community. It is used to write SPAs, has competitors Angular and VueJS. The trend of SPAs got so much attention that everything started to be considered as an application. That created some problems. Let's discuss them one-by-one.
-
In React (as well as in all the SPA libraries), only a single page is created, and it is keep updating as per the user interactions using the JavaScript bundle. That bundle keeps growing as your application is not divided into pages, but it is just a single page. That was a big pain, as at the first time the user opens the site, it takes more than usual time to start the application. It is a well-known limitation, so React, introduced code-splitting using lazy import and suspense. It solves this problem to some extent, but not completely.
-
Slow first-time load
-
As the size of the bundle is increased so much, that bundle will download when you first time opens the site for a huge amount of time for a typical website. It will affect your SEO as well as user experience, so the speed of the React after that load time will lose a bit of value, as many users do not wait for that much in a page while loading and just open some other page, this is one of the reason, this is considered in the SEO metric.
-
Page without content after page load.
-
The whole SPA works on AJAX. So after your page loads, it shows you a loader while fetching the data to populate on your page. This is a big problem for search engines. As when a search engine crawls the page, what it crawl, is an empty page with a loader and will mark it as the soft 404. It also affects your SEO and server-side rendered pages (like php) wins points against ajax based applications. Google understands this problem, and its bot now waits for longer (around 20-30 seconds) to let the pages fetch their data via ajax.
-
Meta info fetching problem.
-
Suppose you're sharing your webpage on Twitter, you are expecting it to show the link preview with a title, description, and an image. But every time you share, you only see the title as React App (or the text you've replaced in your index.html title tag). It happens because the meta-information came from the content, that is loaded after the page load, but unfortunately, Twitter (or any other platform) won't wait for your content to load, it just doesn't know if any content is being loaded, and it won't fetch any meta information but the default. Devs use pre-rendering server and keep HTML pages for each URL, to overcome this. I too did this, you can check out my GitHub repo html-cooker.
But thanks to Next.js, they counter each limitation beautifully. You'll know ahead, how Next.js solves all these problems and also gives you some perks. I won't go into the detailing of each feature of Next.js, but introduce you to how that feature makes the Next.js your next choice.
2. Next.js: From Single to Multi-Page Application
You started from multi-page websites, then you learned ReactJS, SPA library, and you must be wondering, why in the world back to Multi-Page Application?
If you are aware of the React Suspense, means you have done code splitting for bundle size reduction at some level. If you haven't, then I would suggest, go and have a look into it, as Next.js also based on that.
In react suspense, we lazily load the part of our React Tree which is not required to show the current page, it is mostly used in the react-router routes. So you basically divide your applications, into pages, and you request the part of your application bundle which is required to show the content of the current page. Isn't it sounds like, you've divided your application into multiple pages? Yes, you have, and maybe from there, the motivation arises for the Next.js.
So unlike Reactjs, where you build a tree, originating from index.js > App.js and so on, in Next.js you create pages. Yes, and when a page is accessed from the browser, all the other pages do not load with it, which decreases the load time of your page by a huge amount. That is what we wanted to achieve from React Suspense. Next.js did it internally and efficiently. So, it is not the Next.js, who's asking you to covert your SPA into MPA, but you also do it in react unknowingly while using lazy-load and Suspense.
Now a perk comes with Next.js here. Next.js provides a link component, to navigate to other pages without reloading the whole page (smells like ReactJS?). So the perk here is, once a page is loaded, it automatically checks all the links used in the page, and load them in the background, so when the user clicks on any link to navigate to other pages, it is already been loaded and included into the tree. That gives you a feel of ultra-fast experience without loading the whole thing in the beginning like in ReactJS.
3. Game-changing concept: Static Site Generation (SSG)
You must have heard that Next.js is a ReactJS framework for SSR. Honestly, I don't like SSR, but I too came to Next.js for SSR, as it was the need on the ReactJS website. But then I saw a great concept of Static Generation, which just introduced a few months back from today (27, July 2020).
In this, those pages which are populating data from the database (simply, dynamic pages), get statically generated and serve like a very simple HTML page, it causes the page load time ultra-fast. It's like you are accessing a traditional HTML website, with a feel of React (no page refresh).
Now, you must be thinking, that some parts of the page show data differently, from user to user, so static generation will fail there. But, fortunately, NO. Let's understand it with a use case example.
Suppose you have an application, that has a detail page of a hotel. Now, there is hotel information and user's reservation information. So, here the hotel information does not vary user to user, but the reservation information changes. So you can statically generate the hotel page with detail in it, so when search-engine access that page, it has access to the hotel details, with faster load time, now, you can write logic at the client-side to check if the user is logged in or not and if logged in, then the reservation info can be fetched, through ajax. So, here ajax and client-side rendering do not have the disadvantage, as search engines don't need to see the user's reservation details. So, that way you can create a hybrid of CSR and SSG without annoying crawling bots.
4. Next.js is an Extension of React.js, not a replacement.
If there's something in your mind, that you don't want to leave ReactJS for a new framework, then please get rid of it. You can call plain ReactJS application a Next.js application, with everything that comes on a single page. What Next.js do is just divide the different URLs to different pages to boost the performance. You can do and write anything in Next.js that you write in ReactJS, without any second thoughts, you won't lose the ReactJS feel. Next.js is just en extension of ReactJS, not a replacement.
5. Now, there are some commonly asked questions of ReactJS developers about Next.js
Q1. Is there a tree in next.js just like React.js?
Yes, there is. What Next.js do is, request the only resource which is required to show the current page and create a partial tree. And when the other resources are loaded, they just got added into the previous partial tree, so that when you go back to the previous page, it won't load those resources again, which is an important ingredient of ReactJS which is kept in Next.js too.
Q2. Can I access window object in server-side rendering??
Yes! You have access. You can access the window object in useEffect and its equivalent life cycle methods. Or you can simply access it anywhere with a condition as shown below.
if(window){
var scrollTop = window.pageYOffset;
}
Q3. Can I use Material-UI and redux libraries in next.js?
Yes of course. Even Material UI has added a section for their server-side setup. In case you don't know, the Material-UI documentation website also made in Next.js. And you can simply use redux as you use in your React application, but for server-side access to your store, you may need a third-party library.
Q4. Is there any root file in next.js like in react.js?
Yes, there is, you can configure your react store, wrap your whole app with some component, for example, redux store provider or MUI theme provider, etc. But you have to keep them with minimum imports, as they will load in case of any page access as they are the wrapper and root of your React tree.
6. Limitation: Nothing is perfect
I'm not being biased here about Next.js. It definitely has a lot of features that worth considering it at least once, but before you move, there are a few things you must know that you may not like.
-
Delay accessing window object
For the pages, which are being rendered at the server (SSR & SSG), has no access to the
window
object, but as I mentioned above, you can still access it, after the component is mounted, so there's a bit of delay here.So, at the time of mount, the page always considered as either mobile or desktop (what you have set default) then, some calculation will be done using window object, then the actual device-width is calculated to show the content on your page.
-
Static Site Generation: Requires build for every change
So, one of the most annoying limitations of SSG is that they are generated at the build time. So unlike ReactJS, where you just made some changes on the content of the page, and reload it, the content will reflect there. This isn't the case here. Every time you want to change any content of the page, you have to re-build the whole application to reflect it on your site.
So what I do in that scenario, is start a dev server which always does SSR and no SSG, pointed on production, make changes on the data and see the changes at realtime on the dev server. Once everything seems fine, then I build the application to reflect on the production server. There were cases where I re-built the application a couple of times consecutively, but this is something I would tolerate for getting such a great framework.
7. Conclusion
As I mentioned above, I am not biased about Next.js, and honestly, it is not suitable for every any kind of application. Yes!, you read it correctly. You must be thinking now, I write a whole article praising Next.js features and in the conclusion, I am saying it is not suitable for any kind of application. So, here I am going to define web application and differing it from web sites and also hybrids of both.
So, when you're going to start a project, you have to ask yourself a question, is it a web application, or website, or both? Let's take examples of a few, and we'll try to define them, whether they are web-apps, web sites, or their combination.
So, say you have a project that shows user's information about restaurants near them, and dishes popular in that place and available in the restaurants. Users can log in, and leave reviews and ratings to the restaurants. For this, you have an admin panel to manage the content.
One way of defining it is, check if your project is divided into different pages or a couple of screens that just showing different UI components. A website is divided into pages, and an application, into the screen views.
So it seems that the client-side a bit more of a website as there is a list of places and dishes pages, detail pages. It also has review forms (which may be a page or just a simple dialog form), a user profile screen, and login/sign up forms. So the major part of the client-side is in pages, so we can put it in the website category and choose Next.js for it.
On the other hand, the admin-side has one dashboard, which keeps changing its content according to the selected tab, so we can say, it is divided into multiple screen-views. So we can say, it is an application.
Another way of defining is, we want search engines to crawl of websites, but there's nothing to crawl in an application. We want our websites' content dishes, places, etc. to be crawled by search engines but not the admin side. So, vanilla (pure) ReactJS should be the choice for the admin-side as Next.js features are totally irrelevant for admin.
Some more examples of the web application can be, Google Adsense, Google Analytics, etc. While amazon.com, Medium, etc. are more of a website than the web-apps.
Most of the web applications have a blog section, to increase their domain authority and popularize their domain, as their application does not have much content to be crawled by search engines.