It simplifies development workflow, provides many built-in solutions and optimizations, simply put. Next.js is a React framework that employs the latter to make a developer’s life easier when creating web apps.
How did I develop web apps/websites before
It’s sort of a retrospective on how things were before fancy technologies. It’s a short journey on how do we come up with React. Feel free to skip it and read more about Next.js in the next sections.
Pure HTML, CSS era: simple websites
When I was getting started with web development, I put simple <div>
blocks into Notepad, adding some CSS styles. It’s straightforward. I don’t need to know any frameworks, additional technologies. A few more <div>
blocks, then some text and buttons, and I got a sidebar, a menu, and a content block with text.
The problem with this approach begins when I want to add more pages: I should copy-paste those sidebar and menu codes into the new page. As a result, I should amend the code on every page if I want to change, say, the color of the button placed on every page in a header.
Not an ideal method, but it works well for a plain one-page website.
Using template engines to re-use components
There were(and still are) tools that decreased code duplication. Tools like Pug and others are Javascript scripts that compile custom HTML syntax into standard HTML. With their help, a developer can create one component(e.g. a header with links) and put it on many pages without duplicating the component code. If I need to change the component style or structure, I alter the code in one place.
They also provide helpers to format HTML. For example, Javascript functions to capitalize text. Now it’s easier to build a multi-page website. I create multiple fundamental components for my website and I re-use them on almost every page.
From websites to web apps: handling an app’s state
There was a time when businesses started to replace desktop apps with web apps. The other ones wanted to automate many things for customers. They began creating websites to receive orders, for example. When we create a many-page website with custom logic to handle users’ input, sending data to a server, showing errors, etc., it becomes harder to manage the state. State? We need to store, memorize what users want, what did we show/tell them, and so on.
We may keep state on a server, but in such a way we add more complexity there. Also, it’s not always convenient. For example, I want to store a lot of info about the current user and use it immediately on the next page, then forget about it. Say, it’s transforming a picture into a black-and-white one via Javascript. It’d be more efficient to not load our server and make such a transformation client-side.
We could store a state, or even many states, in a browser’s local storage, or IndexedDB, right? Correct. However, we then need to have a logic to update our UI if the state changes. We might update everything when anything in our state changes, but then another issue appears. Our website’s responsiveness isn’t fine: performance is bad.
React, Vue, and similar tools
React, for example, solves the components issue(templating), state management problem. With it, I may create optimized web apps, simplify interactions between many components. Why choose React or Vue? They ease the development of complicated web apps. Handling local(component-level) and global state is simpler. Re-using components is much simpler. These tools are libraries, not opinionated, hence not giving you plain constraints: what you should and shouldn’t do. Instead, they tell you rules of good behavior – what code is better to avoid, for example, when writing components.
React: pros and cons
Pro: reusability of components
We talked about how it was difficult to not duplicate code in other web pages. React allows a developer to create small, large components and re-use them anywhere. We may include small components into bigger ones and include them in larger components. Thus, we diminish repeatable code and we have full control of a local component state. Hence, we optimize a web app(or, we make it worse).
Pro: it’s performant because of virtual DOM
React creates an additional layer of API of DOM to optimize performance. Since the library allows you to create UI consisting of many components, it tries to update an as small number of them as possible to avoid the standard load on a browser’s re-rendering. By standard, I mean not updating the entire web page when we have only a minor state change. Why re-draw all elements in DOM if we can re-draw the ones that depend on the modified data, right?
Pro: a massive community
Any great technology is backed up by a large community. If it’s not large, then it’s difficult to find answers on weird(or any) issues on Stackoverflow, or, to find a library to draw a simple green circle. In the Javascript world, this community is among the largest. The same applies to React, a part of it.
If I need to make a well-styled table in React, I may find it in a moment on Google. If I have hard times figuring out some peculiar behavior with the library, it’s easy to find an answer.
Cons: not for me
React works well for the problems it solves. It’s easy to instantiate a new project and start coding. For me, it’s not difficult to learn. And, later, it speeds up the development. Then why this article about Next.js?
Next.js advantages after using React
React community created create-react-app
CLI tool to instantiate a new project and see the result immediately. And I liked that for my simple web apps.
However, my next projects had public pages, a blog. A solution could be to set up a server and render the pages there, to return prepared HTML. Or, to bring other tools: a blog engine, a static site engine.
Built-in server/static rendering
Next.js cares about this and lets a developer continue writing code. It’s why I didn’t need to use other tools to build a blog or a regular page optimized for search engines and performance.
Why care about server rendering?
When exposing a web page to search engines, it’s better to provide them HTML page without Javascript. Google, for example, can also understand Javascript there(hence a regular React app can be “understood”), but it sends a website to a rendering queue, which takes more time than processing pages when a Googlebot is reading a website right now.
Server rendering may come with a complex setup if one tries this for the first time: I need a server, at least, to render those web pages there.
The other thing intertwined with the previous one is improved performance for users(and search bots). A server renders a page and browsers show it without the necessity to compile Javascript. It comes with an additional load on the server though: it should render a page for every user(especially if the page consists of dynamic data).
We could cache such pages or make them not so dynamic. Anyway, they will be fetched and shown fast for a user. Consequently, our web vitals become better.
Next.js allows me to create a page that is pre-rendered by default. Either at build time(static generation, pages are reused for every request) or at a compile-time(SSR, hence rendering on every request). Static generation is a preferred way since it generates pages at build time. Even if I have dynamic data on the pages but I can fetch it at build time, it’s an ideal way to optimize performance.
Programmatic SEO
Programmatic SEO is a technique to automate creating a lot of web pages that target almost similar keywords. They may have one search intent but it varies in details. Imagine you have an agency that lists realtors in different cities and countries: to help people who look for an apartment to find agents quickly. You make a website with the primary keyword “best realtors”. However, this keyword is popular and a new website won’t gain traction from Google. Hence, we may target long-tail keywords: we save the primary intent(“best realtors”) but specify a location. In this way, “best realtors in Kyiv” isn’t as popular as “best realtors” and we target more specific intent on our web page.
However, we’d require more time to build such pages one by one, right? Most of the code could be copy-pasted, only the list with realtors differs. If we target “best realtors” in 10,000 various cities, it’s a lot of work. What if we want then to target for “best agents in Kyiv”-like keywords? We alter a word, and we require additional 10,000 web pages.
Here’s the thing: we have the realtors lists in various cities already, we have a web page template. With Next.js, building a lot of pages for programmatic SEO is simple. Have a list of keywords, have one code(template) and the framework will build a page for every keyword you specified.
Built-in routing
Remember how do you choose a router for a new React project? They’re almost the same, have some differences, and some libraries are stable. With a Next.js project, I don’t need to think about what router to use this time(maybe some other library?). It has a built-in router. And it’s a simple one: you put a file in the pages
folder and it becomes a page.
For example, I want to make a page with the URL <myapp>/sign-in
. I put sign-in.tsx
component or sign-in
folder with index.tsx
component there and it works.
The router provides all the necessary features: dynamic routes, nested routes, linking pages.
Built-in API server
There’s pages/api
folder where I may specify API endpoints. Some good use cases are:
- API middlewares. When I want to alter a request(e.g. its headers) to make another one to a different server, for example.
- Request resources on other domains. To avoid the CORS issue(an example project). Oftentimes, I need to request some 3rd-party resource, but I can’t due to CORS. One solution is to make a server, make the request there, and then redirect it to the 3rd-party. Let’s save time though. For simple requests(and even a bit complicated, Next.js can handle it too), it’d better useĀ
pages/api
.
Build-in images and fonts optimization
I don’t want to optimize such assets on every page I code. At the beginning of some project, it’s usually not a top priority. But it’s great when the framework does the 80%-like(there are other complicated optimization tricks we usually don’t need) job at optimizing assets. You paste an image and it’s automatically smaller, without layout shifts, and it lazy-loads!
Environment variables
There are 2 environments that are available when you code a Next.js app: a browser, a server. Environment variables in a browser are visible if one wants to find them in the bundled code. The server variables are hidden since users don’t have access to remote hosts and their code.
With Next.js, I can create both env. variables without setting up webpack and installing another library to handle env. vars for a server. The framework has built-in support for them!
There’s a .env
file where I specify server vars, and in the same file I may specify browser vars by adding a prefix to a var – NEXT_PUBLIC_
. Incredibly convenient to me.
Summary
Next.js saves me time a lot with current and new projects. I can combine a few apps seamlessly and have one codebase only. The advantages I wrote about may not apply to your use case though. If you use React now, it’s worth trying: the framework adds up useful features on top of the React pros.
If you have questions or feedback, let me know.