Nwose Lotanna Web Developer and Writer

What’s new in Next.js 9.2

4 min read 1125

What’s New in Next.js 9.2?

In this article, we’ll break down all the new and shiny features that shipped with the latest version of Next.js.

What is 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.

Built-in CSS support for global stylesheets

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.

Built-in CSS module support for component-level styles

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 (
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.

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.

Improved code splitting strategy

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:

  • A minimal chunk for each page
  • A framework chunk containing React, ReactDOM, React’s Scheduler, etc.
  • Library chunks for any node_module dependency over 160kb (pre-minify/gzip)
  • A commons chunk for code used across all pages
  • As many shared chunks (used by two or more pages) as possible, optimizing for overall application size and initial load speed
  • Next.js client-side runtime
  • Webpack runtime

Catch-all dynamic routes

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'] }

How to get started using Next.js 9.2

You can get started using the new version right away by upgrading your current version.

npm i [email protected] [email protected] [email protected]


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?

LogRocket: Full visibility into production Next.js apps

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 — .

Nwose Lotanna Web Developer and Writer

Leave a Reply