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.
It's sort of a retrospective on how things were before fancy technologies. It's a short journey of how we came up with React. Feel free to skip it and read more about Next.js in the next sections.
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 would copy-paste those sidebar and menu codes into the new page. As a result, I would 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.
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.
There was a time when businesses started to replace desktop apps with web apps. They wanted to automate many things for customers. They began creating websites to receive orders, for example.
When we create a multi-page website with custom logic to handle users' input, send data to a server, show errors, etc., it becomes harder to manage the state. We need to store 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 to the server. 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, but instead, 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, for example, solves the components issue(templating) and the state management problem. With it, I can 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 easier.
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.
We talked about how it was difficult to not duplicate code on other web pages. React allows a developer to create small or 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.
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 as small a 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?
Any great technology is backed up by a large community. If it's not large, then it's difficult to find answers to 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 a hard time figuring out some peculiar behavior with the library, it's easy to find an answer.
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?
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.
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.
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 (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 with plain HTML.
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 to 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 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 detail.
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.
Remember how 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.
There's pages/api
folder where I may specify API endpoints. Some good use cases are:
pages/api
.
I don't want to optimize such assets on every page I code. At the beginning of some projects, it's usually not a top priority. But it's great when the framework does a huge part of the job of optimizing assets(there are other complicated optimization tricks we usually don't need). You paste an image and it's automatically smaller, without layout shifts, and it lazy-loads!
There are 2 environments that are available when you code a Next.js app: a browser and 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. variables for a server. The framework has built-in support for them!
There's a .env
file where I specify server variables, and in the same file I may specify browser variables by adding a prefix to a variable - NEXT_PUBLIC_
. Incredibly convenient to me.
Next.js saves me a lot of time 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 out Next.js, the framework adds up useful features on top of the React pros.
If you have questions or feedback, let me know.
Also published here