In this article, we’ll break down all the new and shiny features that shipped with the latest version of Next.js.
Next.js is self-branded as the React framework for static pages, progressive web apps, mobile web apps, SEO-friendly pages, and, especially, server-side rendering. It facilitates static exporting with just a line of command and ships with a CSS-in-JS library styled JSX. It also includes features such as code splitting, universal rendering, and hot reloading.
According to the latest “State of JavaScript” survey, the Next.js community grew massively in the last 12 months, with the retention rate skyrocketing from 6 percent to 24 percent. The number of new people who are willing to learn Next.js increased by almost 10 percent as well.
Let’s take a detailed look at some of the most noteworthy new features that shipped with the latest version of the framework: Next.js 9.2.
The capability to import CSS with the next-css
plugin extending the behavior of Next.js was shipped in version 5.0. As time went on, the Next team got a lot of feedback regarding the next-css
plugin from companies that use the framework.
In response, the team decided to bring the plugin in-house as a part of the core Next product. Whereas the plugin had previously been limited in its handling of imports — such as cases where imported files dictated global styles for the entire app rather than being scoped to the component level — the Next team developed a workaround. To get started using CSS imports in your application, you can import the CSS file within pages/_app.js
.
Consider the following stylesheet, named styles.css
, in the root of your project.
body { padding: 20px 20px 60px; margin: 0; }
Create a pages/_app.js
file if not already present. Then, import the styles.css
file.
import '../styles.css' // This default export is required in a new `pages/_app.js` file. export default function MyApp({ Component, pageProps }) { return <Component {...pageProps} /> }
Since stylesheets are global by nature, they must be imported in the custom <App>
component to avoid class name and ordering conflicts for global styles. This makes it possible for your styles to reflect on your app as you edit them in the development environment.
In production, all the stylesheets will be minified into one .css
file and loaded through a link tag in the index.html
file that Next serves. This feature is backward-compatible, and if you already achieve this with another library, the feature is disabled by default to avoid conflicts.
Another issue with the old next-css
plugin was the fact that all your .css
files were either handled as global styles or local styles and there was no option to enable both at once. In this new version, CSS modules are now supported so you can use global CSS and CSS modules simultaneously.
With CSS modules, you can scope CSS locally by classnames and import them anywhere in your app to achieve scoping or component-level styling. Consider, for example, a reusable Button
component in the components/
folder.
First, create components/Button.module.css
with the following content.
/* You do not need to worry about .error {} colliding with any other `.css` or `.module.css` files! */ .error { color: white; background-color: red; }
Then, create components/Button.js
, importing and using the above CSS file.
import styles from './Button.module.css' export function Button() { return ( <button type="button" // Note how the "error" class is accessed as a property on the imported // `styles` object. className={styles.error} > Destroy </button> ) } >
In this version, CSS modules are opt-in and only enabled for files with the .module.css
extension; the normal link stylesheets and global CSS files are still supported. This feature is backward-compatible, and if you already achieve this with another library, again, the feature is disabled by default to avoid conflicts.
For a Next.js app to load, five fixed JavaScript bundles must load to boot up React: the main JS file, a common JS file, the Next runtime bundle, the Webpack runtime bundle, and dynamic imports. Code splitting helps to optimize the process of loading up all these files.
The initial code splitting strategy the Next team employed was for the commons bundle. It was a usage-ratio heuristic strategy to ensure that if a module was used in more than half of all pages, it would be marked as a module; otherwise, it would be bundled. While the team found this method to be beneficial, over time it realized that it could optimize the process even further.
The new strategy allows you to optimize common chunks with multiple files, including when many page types are involved. This is now the default process moving forward from this version.
The new chunking implementation leverages HTTP/2 to deliver a greater number of smaller-sized chunks. Under the new heuristic, myriad chunks are created for various purposes:
node_module
dependency over 160kb (pre-minify/gzip)Dynamic route segments were introduced in Next 9.0. The goal was to simplify dynamic segments in Next.js without using a custom server. The feature has enjoyed widespread adoption, and the Next team has been trying to optimize it as much as possible.
Previously, dynamic routes did not cover catch-all routes. In the new version, you can now use catch-all routes by using the [...name]
syntax. This is especially useful when you have a nested structure that is defined by a content source, such as a CMS.
For example, pages/post/[...slug].js
will match /post/a
, /post/a/b
, /post/a/b/c
, and so on.
slug
is provided in the router query object as an array of individual path parts. So for the path post/foo/bar
, the query object will be { slug: ['foo', 'bar'] }
You can get started using the new version right away by upgrading your current version.
npm i next@latest react@latest react-dom@latest
The Next community has been showing impressive growth numbers, as evidenced by its nearly 900 contributors, 44,000+ GitHub stars, a vast number of example directories, and a 13,800-member spectrum forum. These numbers are poised to keep increasing steadily as the team continues to focus on improving the developer experience and optimizing the Next product.
What is your favorite feature of Next 9.2?
Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your Next.js apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowAuth.js makes adding authentication to web apps easier and more secure. Let’s discuss why you should use it in your projects.
Compare Auth.js and Lucia Auth for Next.js authentication, exploring their features, session management differences, and design paradigms.
While animations may not always be the most exciting aspect for us developers, they’re essential to keep users engaged. In […]
Astro, renowned for its developer-friendly experience and focus on performance, has recently released a new version, 4.10. This version introduces […]