One of Next.js's primary goals is to provide the best production performance with the best possible developer experience. This release brings about many significant improvements to the build and debug pipelines
Rendering accurate and help errors is critical to a great development and debugging experience. Until now, we would render the error message and its stack trace. Moving forward, we make use of react-error-overlay to enrich the stack trace with:
Accurate error locations for both server and client errors
Highlights of the source to provide context
A full rich stack trace
This is a comparison of the before and after of our errors:
The previous overlay left, react-error-overlay right
As a bonus, react-error-overlay makes it easy to open your text editor by just clicking on a specific code block.
Since its very first release Next.js has been powered by webpack for bundling your code and re-using the rich ecosystem of plugins and extensions. We're excited to announce Next.js is now powered by the latest webpack 4, which comes with numerous improvements and bugfixes.
Among these we get:
Support for .mjs source files
Code splitting improvements
Better tree-shaking (removal of unused code) support
Another new feature is WebAssembly support, Next.js can even server-render WebAssembly, here is an example.
Note: this upgrade is fully backwards-compatible. However, if you are using custom webpack loaders or plugins via next.config.js, you might have to upgrade them.
The new version of these Next.js plugins solves 20 existing issues related to CSS imports; As an example, importing CSS in dynamic import()s is now supported:
components/my-dynamic-component.js
import './my-dynamic-component.css';export default function MyDynamicComponent() { return <h1>My dynamic component</h1>;}
pages/index.js
import dynamic from 'next/dynamic'const MyDynamicComponent = dynamic(import('../components/my-dynamic-component'))export default function Index() { return () { <div> <MyDynamicComponent/> </div> }}
A major improvement is that you are no longer required to add the following to pages/_document.js:
Instead, Next.js automatically injects the CSS file. In production, Next.js also automatically adds a content hash to the CSS URL, so that if there are changes, to ensure that your end-users never get stale versions of the file and have the ability to introduce immutable permanent caching.
In short, all you have to do to support importing .css files in your Next.js project is to just register the withCSS plugin in your next.config.js:
const withCSS = require('@zeit/next-css');module.exports = withCSS({ /* my next config */});
Another example is using import() without being wrapped in the next/dynamic module.
Starting with Next.js 7 we no longer touch the default import() behavior. This means you get full import() support out of the box.
This change is fully backwards-compatible as well. Making use of a dynamic component remains as simple as:
pages/index.js
import dynamic from 'next/dynamic';const MyComponent = dynamic(import('../components/my-component'));export default function Index() { return ( <div> <MyComponent /> </div> );}
What this example does is create a new JavaScript file for my-component and only load it when <MyComponent /> is rendered.
Most importantly, if it is not rendered, the <script> tag is not included in the initial HTML document payload.
To further simplify our codebase and make use of the excellent React ecosystem, in Next.js 7 next/dynamic was re-written to make use of react-loadable behind the scenes (with some minor modifications). This also introduces two great new features for dynamic components:
Timeouts using the timeout option on next/dynamic
A loading component delay, using the delay option on next/dynamic. This delay allows your loading component to wait x time before rendering the loading state, for example, if the import is very fast.
Next.js 6 introduced Babel 7 while it was still in beta. Since then the stable version of Babel 7 has been released, and Next.js 7 now using this version.
For a full list of changes, you can refer to Babel its release notes.
overrides property to apply presets/plugins only to a subset of files or directories
If you do not have a custom Babel configuration in your Next.js project, there are no breaking changes.
If you do however have a custom Babel configuration, you have to upgrade the respective custom plugins/presets to their latest version.
In case you are upgrading from a version below Next.js 6 you can run the excellent babel-upgrade tool.
In addition to upgrading to Babel 7, the Next.js Babel preset (next/babel) now defaults to setting the modules option to commonjs when NODE_ENV is set to test.
This configuration option was often the only reason for creating a custom .babelrc in a Next.js project:
As Next.js pre-renders HTML, it wraps pages into a default structure with <html>, <head>, <body> and the JavaScript files needed to render the page.
This initial payload was previously around 1.62kB. With Next.js 7 we've optimized the initial HTML payload, it is now 1.5kB, a 7.4% reduction, making your pages leaner.
6.0
7.0
delta
Document size (server rendered)
1.62kb
1.50kb
7.4%smaller
The main ways we have reduced size are:
The __next-error div is removed
The inline scripts are minified, in a future release they will be completely removed
Compiled away unused __NEXT_DATA__ properties when they are not used, for example, the nextExport and assetPrefix properties.
In Next.js 5 we introduced assetPrefix support, a way to make Next.js automatically load assets from a certain location, usually a CDN. This option works great if your CDN supports proxying, you request an URL like
Typically, the CDN checks if it has the file in its cache, or otherwise requests it directly from the origin.
Proxying assets is precisely how the Edge Network works.
However, some solutions require pre-uploading a directory directly into the CDN. The problem in doing this is that Next.js its URL structure did not match the folder structure inside the .next folder. For example our earlier example
While we do recommend using the proxying type of CDN, this new structure allows users of a different type of CDN to upload the .next directory to their CDN.
We are excited to introduce styled-jsx 3, the by default included CSS-in-JS solution in Next.js is now ready for React Suspense.
One thing that was often unclear was how to style a child component if that component is not part of the current component scope, for example, if you included a child component that needed specific styles only when used inside the parent component:
The above code tries to select the p tag does not work because styled-jsx styles are scoped to the current component, they do not leak into child components. One way to get around this was using the :global method, removing the prefix from the p tag. However, this introduces a new issue, which is that styles do leak across the page.
In styled-jsx 3 this issue has been solved by introducing a new API, css.resolve, which will generate the className and <style>
tags (the styles property) for the given styled-jsx string:
This new API allows for transparently passing through custom styling to child components.
Since this is a major release for styled-jsx, there is one breaking change that improves bundle sizes if you are using styles-jsx/css.
In styled-jsx 2 we would generate a "scoped" and "global" version of external styles, even when only the "scoped" version was used we would still include the "global" version of those external styles.
With styled-jsx 3 global styles have to be tagged with css.global instead of css, so that styled-jsx can optimize bundle size.
Starting from Next.js 7 we now support the new React context API between pages/_app.js and page components.
Previously it was not possible to use React context in between pages on the server side. The reason for this was that webpack keeps an internal module cache instead of using require.cache, we've written a custom webpack plugin that changes this behavior to share module instances between pages.
In doing so we not only allow usage of the new React context, but also reduce Next.js's memory footprint when sharing code between pages.
The blog post you are currently reading is already part of the new blog section on nextjs.org. This blog will be the new home for communication related to Next.js, for example, new version announcements.
As the amount of apps using Next.js is continuously growing, we needed a way to show all these beautiful apps in one overview. Meet the new /showcase page:
Get inspired on nextjs.org/showcase
This new showcase allows us to add new apps built with Next.js continuously.
We invite you to visit /showcase to get inspired, or submit your app that uses Next.js!
Ever since it's first release Next.js has been used in everything from fortune 500 companies to personal blogs. We're very excited to see the growth in Next.js adoption.
Currently, there are over 12,500 publicly indexed domains using Next.js.
We've had over 500 contributors landing at least 1 commit.
On GitHub, the project has been starred over 29,000 times.
Almost 2200 pull requests were submitted since the first release.
The Next.js community has nearly 2000 members. Join us!
After 26 canary releases and 3.4 million downloads, we are proud to introduce the production-ready Next.js 7, featuring:
Finally, we are excited to be sharing this news on the all-new Nextjs.org
Copy link to headingDX Improvements
One of Next.js's primary goals is to provide the best production performance with the best possible developer experience. This release brings about many significant improvements to the build and debug pipelines
Copy link to headingCompilation Speed
Thanks to webpack 4, Babel 7 and many improvements and optimizations on our codebase, Next.js now boots up to 57% faster during development.
Thanks to our new incremental compilation cache, changes you make to the code will now build 40% faster.
These are some example figures we have collected:
As a bonus, when developing and building you will now see better realtime feedback thanks to webpackbar:
Copy link to headingBetter error reporting with React Error Overlay
Rendering accurate and help errors is critical to a great development and debugging experience. Until now, we would render the error message and its stack trace. Moving forward, we make use of
react-error-overlayto enrich the stack trace with:This is a comparison of the before and after of our errors:
As a bonus,
react-error-overlaymakes it easy to open your text editor by just clicking on a specific code block.Copy link to headingWebpack 4
Since its very first release Next.js has been powered by webpack for bundling your code and re-using the rich ecosystem of plugins and extensions. We're excited to announce Next.js is now powered by the latest webpack 4, which comes with numerous improvements and bugfixes.
Among these we get:
.mjssource filesAnother new feature is WebAssembly support, Next.js can even server-render WebAssembly, here is an example.
Note: this upgrade is fully backwards-compatible. However, if you are using custom webpack loaders or plugins via next.config.js, you might have to upgrade them.
Copy link to headingCSS Imports
With webpack 4, a new way of extracting CSS from bundles was introduced, called mini-extract-css-plugin.
@zeit/next-css,@zeit/next-less,@zeit/next-sass, and@zeit/next-stylusare now powered bymini-extract-css-plugin.The new version of these Next.js plugins solves 20 existing issues related to CSS imports; As an example, importing CSS in dynamic
import()s is now supported:A major improvement is that you are no longer required to add the following to
pages/_document.js:Instead, Next.js automatically injects the CSS file. In production, Next.js also automatically adds a content hash to the CSS URL, so that if there are changes, to ensure that your end-users never get stale versions of the file and have the ability to introduce immutable permanent caching.
In short, all you have to do to support importing
.cssfiles in your Next.js project is to just register the withCSS plugin in yournext.config.js:Copy link to headingStandardized Dynamic Imports
Next.js has had support for dynamic imports through
next/dynamicsince Version 3.As early adopters of this technology, we had to write our own solution for handling
import().As a consequence, Next.js was beginning to diverge from the support that webpack later introduced for it and some features were missing.
Because of this Next.js did not support a few
import()features webpack has introduced since.For example, naming and bundling certain files together manually was not possible:
Another example is using
import()without being wrapped in thenext/dynamicmodule.Starting with Next.js 7 we no longer touch the default
import()behavior. This means you get full import() support out of the box.This change is fully backwards-compatible as well. Making use of a dynamic component remains as simple as:
What this example does is create a new JavaScript file for
my-componentand only load it when<MyComponent />is rendered.Most importantly, if it is not rendered, the
<script>tag is not included in the initial HTML document payload.To further simplify our codebase and make use of the excellent React ecosystem, in Next.js 7
next/dynamicwas re-written to make use ofreact-loadablebehind the scenes (with some minor modifications). This also introduces two great new features for dynamic components:timeoutoption onnext/dynamicdelayoption onnext/dynamic. This delay allows yourloadingcomponent to wait x time before rendering the loading state, for example, if the import is very fast.Copy link to headingBabel 7
Next.js 6 introduced Babel 7 while it was still in beta. Since then the stable version of Babel 7 has been released, and Next.js 7 now using this version.
For a full list of changes, you can refer to Babel its release notes.
Some of the main features are:
@zeit/next-typescript<>supportbabel.config.jssupportoverridesproperty to apply presets/plugins only to a subset of files or directoriesIf you do not have a custom Babel configuration in your Next.js project, there are no breaking changes.
If you do however have a custom Babel configuration, you have to upgrade the respective custom plugins/presets to their latest version.
In case you are upgrading from a version below Next.js 6 you can run the excellent
babel-upgradetool.In addition to upgrading to Babel 7, the Next.js Babel preset (
next/babel) now defaults to setting themodulesoption tocommonjswhenNODE_ENVis set totest.This configuration option was often the only reason for creating a custom
.babelrcin a Next.js project:With Next.js 7 this becomes:
At this point, the
.babelrccan be removed, as Next.js will then automatically usenext/babelwhen there is no Babel configuration.Copy link to headingSmaller Initial HTML Payload
As Next.js pre-renders HTML, it wraps pages into a default structure with
<html>,<head>,<body>and the JavaScript files needed to render the page.This initial payload was previously around 1.62kB. With Next.js 7 we've optimized the initial HTML payload, it is now 1.5kB, a 7.4% reduction, making your pages leaner.
The main ways we have reduced size are:
__next-errordiv is removed__NEXT_DATA__properties when they are not used, for example, thenextExportandassetPrefixproperties.Copy link to headingStatic CDN Support
In Next.js 5 we introduced
assetPrefixsupport, a way to make Next.js automatically load assets from a certain location, usually a CDN. This option works great if your CDN supports proxying, you request an URL likeTypically, the CDN checks if it has the file in its cache, or otherwise requests it directly from the origin.
Proxying assets is precisely how the Edge Network works.
However, some solutions require pre-uploading a directory directly into the CDN. The problem in doing this is that Next.js its URL structure did not match the folder structure inside the
.nextfolder. For example our earlier exampleWith Next.js 7 we have changed the directory structure of
.nextto match the url structure:While we do recommend using the proxying type of CDN, this new structure allows users of a different type of CDN to upload the
.nextdirectory to their CDN.Copy link to headingStyled JSX v3
We are excited to introduce styled-jsx 3, the by default included CSS-in-JS solution in Next.js is now ready for React Suspense.
One thing that was often unclear was how to style a child component if that component is not part of the current component scope, for example, if you included a child component that needed specific styles only when used inside the parent component:
The above code tries to select the
ptag does not work because styled-jsx styles are scoped to the current component, they do not leak into child components. One way to get around this was using the:globalmethod, removing the prefix from theptag. However, this introduces a new issue, which is that styles do leak across the page.In styled-jsx 3 this issue has been solved by introducing a new API,
css.resolve, which will generate theclassNameand<style>tags (thestylesproperty) for the given styled-jsx string:This new API allows for transparently passing through custom styling to child components.
Since this is a major release for styled-jsx, there is one breaking change that improves bundle sizes if you are using
styles-jsx/css. In styled-jsx 2 we would generate a "scoped" and "global" version of external styles, even when only the "scoped" version was used we would still include the "global" version of those external styles.With styled-jsx 3 global styles have to be tagged with
css.globalinstead ofcss, so that styled-jsx can optimize bundle size.For all changes, please refer to the release notes.
Copy link to headingReact Context with SSR between App and Pages
Starting from Next.js 7 we now support the new React context API between
pages/_app.jsand page components.Previously it was not possible to use React context in between pages on the server side. The reason for this was that webpack keeps an internal module cache instead of using require.cache, we've written a custom webpack plugin that changes this behavior to share module instances between pages.
In doing so we not only allow usage of the new React context, but also reduce Next.js's memory footprint when sharing code between pages.
Copy link to headingnextjs.org
Together with the Next.js 7 release, we are launching a completely redesigned nextjs.org.
Copy link to headingBlog
The blog post you are currently reading is already part of the new blog section on nextjs.org. This blog will be the new home for communication related to Next.js, for example, new version announcements.
Copy link to headingGet Inspired
As the amount of apps using Next.js is continuously growing, we needed a way to show all these beautiful apps in one overview. Meet the new
/showcasepage:This new showcase allows us to add new apps built with Next.js continuously.
We invite you to visit
/showcaseto get inspired, or submit your app that uses Next.js!Copy link to headingCommunity
Ever since it's first release Next.js has been used in everything from fortune 500 companies to personal blogs. We're very excited to see the growth in Next.js adoption.
The Next.js community has nearly 2000 members. Join us!