Next.js and Revolutionary Changes in React
![image](https://habrastorage.org/webt/ew/nl/sx/ewnlsxtwz73sjrfoulqlqspwbpk.png)
React.js is currently one of the most popular libraries for creating modern web applications. React is famous for its flexibility and richness of the ecosystem. One of the significant advantages of this ecosystem is Next.js – and how it is successfully developing. With this framework, it has become much more convenient to develop applications based on React, their capabilities have expanded. In this article, we will look at how Next.js improved React, touch on its features, advantages, and what follows from them.
What is Next.js?
Next.js is an open-source React framework for front-end development that enables, among other things, server-side rendering and static website generation for React-based web applications. It is a higher-level framework than React, built on top of React, and helps standardize the development of fast, scalable, and usable web applications.
Server Side Rendering (SSR) and Static Site Generation (SSG)
With the introduction of Server Side Rendering (SSR) and Static Site Generation (SSG) features in Next.js, the capabilities of React applications have expanded significantly, especially when it comes to search engine optimization (SEO) and performance. Let's take a closer look at how these features help you solve specific problems and find reliable solutions.
Difficulty of working with React:
- React applications are typically rendered in the client's browser. While this client-side rendering is great for interactive web applications, it does have disadvantages, especially regarding SEO and slow initial page loads.
- Search engines sometimes have difficulty indexing pages with JavaScript and client-side renderings, which can negatively impact SEO.
- Client-side rendering also means that the page content is not immediately available because JavaScript needs to be downloaded and run before rendering, which again slows down loading.
To illustrate how Next.js has evolved from traditional React and effectively solves the problems associated with client-side rendering, let's look at a code example. We'll create a simple blog page to demonstrate both SSR and SSG in Next.js.
Example: Blog Page with React (Traditional Approach)
In a typical React configuration, you can fetch blog posts on the client side, like this:
// Blog.js (используется React)
import React, { useState, useEffect } from 'react';
const Blog = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('/api/posts')
.then(response => response.json())
.then(data => setPosts(data));
}, []);
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</div>
);
};
export default Blog;
With this approach, data is collected on the client side, which slows down loading times and worsens SEO performance because content is not immediately indexed by search engines.
Transition to Next.js using SSR
Next.js solution that uses SSR:
- SSR in Next.js renders React components on the server side, pre-generating the full HTML for each page.
- When a user or search bot requests a page, the server sends fully structured HTML, providing immediate access to the content. This helps with SEO as search engines can easily crawl and index the page content.
- SSR also significantly improves performance, especially during initial page load, as users receive a fully rendered page faster.
- This approach is especially useful on content-heavy sites, particularly blogs or online stores, where good SEO and fast content delivery are critical.
In Next.js, we can use server-side rendering to get data before the page is even displayed:
// pages/blog.js (using Next.js with SSR)
import React from 'react';
const Blog = ({ posts }) => (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</div>
);
export async function getServerSideProps() {
const response = await fetch('https://example.com/api/posts');
const posts = await response.json();
return {
props: { posts },
};
}
export default Blog;
Here getServerSideProps gets data from the server before the page is rendered. This ensures that the HTML markup sent to the browser already contains the blog posts.
How it works:
1. Retrieving data on the server: Every time a user requests a page from the blog, getServerSideProps is run on the server.
2. Fetch API: Fetch blog posts from external API. (https://example.com/api/posts).
3. Returning elements: The retrieved posts are returned as elements of the Blog.Render component.
4. Page: Next.js then renders the Blog component server-side using these props and sends the fully rendered HTML to the client.
Use case: This approach is ideal when your blog content changes frequently and you want the page to always display the most current posts.
Best Examples of Using Static Site Generation (SSG)
1. Blogs and websites with documentation:
- Content that changes rarely is ideal for SSG.
- Fast loading and superior SEO performance since pages are pre-rendered to static HTML.
2. Marketing websites:
- Corporate, landing or portfolio pages where the content is mostly static.
- SSG provides high performance, which is very important for user experience and SEO purposes.
3. Lists of products in online stores:
- For pages whose content changes infrequently, such as product listings.
- Speeds up page loading, making shopping more enjoyable.
4. Portals with publicly accessible content:
- News sites or educational resources with static articles.
- SSG can handle high traffic with ease thanks to CDN caching.
Implementation of Static Site Generation (SSG)
Dynamic rendering issues:
- Dynamic page rendering, while powerful, can be resource intensive and slower than traditional approaches because the server must re-render the page for each request.
- This can cause performance bottlenecks, especially in high traffic situations.
Next.js solution using SSG:
- With SSG, Next.js pre-renders pages during build time. This means that static HTML files for each page are generated in advance.
- These static files can be served directly from the CDN, significantly reducing server load and speeding up content delivery.
- SSG is ideal for sites with content that doesn't change frequently, such as documentation sites, blogs, or marketing pages.
- This approach also ensures near-instant loading and reduces the load on the server since it doesn't have to render pages for every request.
- Next.js also enables incremental static regeneration (ISR), where pages are refreshed at set intervals or on demand, keeping content fresh without impacting performance.
If blog posts don't change often, we can use static site generation to improve performance:
// pages/blog.js (использование Next.js с SSG)
import React from 'react';
const Blog = ({ posts }) => (
// ... как и ранее
);
export async function getStaticProps() {
const response = await fetch('https://example.com/api/posts');
const posts = await response.json();
return {
props: { posts },
revalidate: 10, // Инкрементная статическая регенерация (ISR), на которую требуются считанные секунды
};
}
export default Blog;
In this case, the page is generated during the build and served as a static file. Using the incremental static regeneration feature (revalidate option), the page can be updated periodically, ensuring freshness of the content.
How it works:
1. Fetching data at build time: getStaticProps runs at build time, fetching blog posts from the API.
2. Static generation: The Blog page is pre-rendered as static HTML with the received data.
3. Revalidate: The revalidate key set to 10 enables the ISR. It tells Next.js to refresh the page no more than once every 10 seconds if new requests come in.
4. Serving a static page: The statically generated page is served to users. If the page is requested again after 10 seconds and the data has changed, Next.js regenerates the page with the updated content.
Example of use: This method is suitable for blog content that does not require real-time updates. ISR ensures that the content is up-to-date by periodically refreshing the page.
Best Use Cases for Server Side Rendering (SSR)
1. Dynamic custom panels:
- Applications where the content is user-specific and changes frequently, such as user panels in SaaS applications.
- SSR ensures that content is relevant and personalized for each user.
2. E-commerce sites with dynamic content:
- Pages with frequently changing content, such as price lists, product availability, or user reviews.
- SSR can dynamically generate pages based on incoming data in real time.
3. Social networks:
- Sites with rapidly changing content, such as social media feeds or forums.
- SSR allows for dynamic display of content, which is very important for such interactive platforms.
4. Sites characterized by intense interaction with users and real-time data:
- Applications such as online trading platforms, live sports streaming or interactive gaming sites.
- SSR helps provide relevant content every time a request is made, which is essential for real-time data accuracy.
Choosing between SSG and SSR
Trade-off between performance and data freshness:
- SSG provides better performance and scalability because it serves static files.
- SSR provides fresher content, but the approach itself can be more resource intensive.
SEO Aspects:
- Both SSG and SSR are suitable for SEO. SSG can benefit from faster loading times, but SSR is more suitable for dynamic content that needs to be indexed.
Development and maintenance:
- SSGs are generally easier to develop and maintain for sites with static content.
- SSR can be more complex, but is necessary for dynamic, user-facing applications.
Conclusion
By combining SSR and SSG, Next.js provides developers with powerful tools to overcome the limitations of client-side rendering in React. These techniques improve search engine optimization, provide faster loading times, and more efficient use of server resources. The choice between SSR and SSG (or a hybrid approach) can be made depending on the specific needs of the application, whether dynamic interactivity or optimized performance is more important to you. This flexibility is a significant advance in building modern, scalable, and high-performance web applications with React.