@nx/next

When using Next.js in Nx, you get the out-of-the-box support for TypeScript, Cypress, and Jest. No need to configure anything: watch mode, source maps, and typings just work.

The Next.js plugin contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides:

  • Scaffolding for creating, building, serving, linting, and testing Next.js applications.
  • Integration with building, serving, and exporting a Next.js application.
  • Integration with React libraries within the workspace.

Setting up @nx/next

To create a new Nx workspace with Next.js, run:

npx create-nx-workspace@latest --preset=next

Installation

Keep Nx Package Versions In Sync

Make sure to install the @nx/next version that matches the version of nx in your repository. If the version numbers get out of sync, you can encounter some difficult to debug errors. You can fix Nx version mismatches with this recipe.

In any workspace, you can install @nx/next by running the following command:

nx add @nx/next

This will install the correct version of @nx/next.

How @nx/next Infers Tasks

Inferred Tasks

Since Nx 18, Nx plugins can infer tasks for your projects based on the configuration of different tools. You can read more about it at the Inferred Tasks concept page.

The @nx/next plugin will create tasks for any project that has a Next.js configuration file preset. Any of the following files will be recognized as a Next.js configuration file:

  • next.config.js
  • next.config.cjs
  • next.config.mjs

View Inferred Tasks

To view inferred tasks for a project, open the project details view in Nx Console or run nx show project <project-name> --web in your command line.

@nx/next Configuration

The @nx/next/plugin is configured in the plugins array in nx.json.

nx.json
1{ 2 "plugins": [ 3 { 4 "plugin": "@nx/next/plugin", 5 "options": { 6 "buildTargetName": "build", 7 "devTargetName": "dev", 8 "startTargetName": "start", 9 "serveStaticTargetName": "serve-static" 10 } 11 } 12 ] 13} 14
  • The buildTargetName option controls the name of Next.js' compilation task which compiles the application for production deployment. The default name is build.
  • The devTargetName option controls the name of Next.js' development serve task which starts the application in development mode. The default name is dev.
  • The startTargetName option controls the name of Next.js' production serve task which starts the application in production mode. The default name is start.
  • The serveStaticTargetName option controls the name of Next.js' static export task which exports the application to static HTML files. The default name is serve-static.

Using @nx/next

Creating Applications

You can add a new application with the following:

nx g @nx/next:app apps/my-new-app

Generating Libraries

Nx allows you to create libraries with just one command. Some reasons you might want to create a library include:

  • Share code between applications
  • Publish a package to be used outside the monorepo
  • Better visualize the architecture using nx graph

To generate a new library run:

nx g @nx/next:lib libs/my-new-lib

Generating Pages and Components

Nx also provides commands to quickly generate new pages and components for your application.

nx g @nx/next:page apps/my-new-app/pages/my-new-page

nx g @nx/next:component apps/my-new-app/components/my-new-component

Above commands will add a new page my-new-page and a component my-new-component to my-new-app project respectively in the specified directories.

Nx generates components with tests by default. For pages, you can pass the --withTests option to generate tests under the specs folder.

Using Next.js

Serving Next.js Applications

You can serve a Next.js application my-new-app for development:

nx dev my-new-app

To serve a Next.js application for production:

nx start my-new-app

This will start the server at http://localhost:3000 by default.

Using an Nx Library in your Application

You can import a library called my-new-lib in your application as follows.

apps/my-next-app/pages/index.tsx
1import { MyNewLib } from '@<your nx workspace name>/my-new-lib'; 2 3export function Index() { 4 return ( 5 <MyNewLib> 6 <p>The main content</p> 7 </MyNewLib> 8 ); 9} 10 11export default Index; 12

There is no need to build the library prior to using it. When you update your library, the Next.js application will automatically pick up the changes.

Publishable libraries

For libraries intended to be built and published to a registry (e.g. npm) you can use the --publishable and --importPath options.

nx g @nx/next:lib libs/my-new-lib --publishable --importPath=@happynrwl/ui-components

Testing Projects

You can run unit tests with:

nx test my-new-app

nx test my-new-lib

Replace my-new-app and my-new-lib with the name or the project you want to test. This command works for both applications and libraries.

You can also run E2E tests for applications:

nx e2e my-new-app-e2e

Replace my-new-app-e2e with the name or your project with -e2e appended.

Linting Projects

You can lint projects with:

nx lint my-new-app

nx lint my-new-lib

Replace my-new-app and my-new-lib with the name or the project you want to test. This command works for both applications and libraries.

Building Projects

Next.js applications can be build with:

nx build my-new-app

And if you generated a library with --buildable, then you can build a library as well:

nx build my-new-lib

After running a build, the output will be in the dist folder. You can customize the output folder by setting outputPath in the project's project.json file.

The library in dist is publishable to npm or a private registry.

Static HTML Export

Next.js applications can be statically exported by changing the output inside your Next.js configuration file.

apps/my-next-app/next.config.js
1const nextConfig = { 2 nx: { 3 svgr: false, 4 }, 5 output: 'export', 6}; 7

After setting the output to export, you can run the build command to generate the static HTML files.

nx build my-next-app

You can then check your project folder for the out folder which contains the static HTML files.

1├── index.d.ts 2├── jest.config.ts 3├── next-env.d.ts 4├── next.config.js 5├── out 6├── project.json 7├── public 8├── specs 9├── src 10├── tsconfig.json 11└── tsconfig.spec.json 12

E2E testing

You can perform end-to-end (E2E) testing on static HTML files using a test runner like Cypress. When you create a Next.js application, Nx automatically creates a serve-static target. This target is designed to serve the static HTML files produced by the build command.

This feature is particularly useful for testing in continuous integration (CI) pipelines, where resources may be constrained. Unlike the dev and start targets, serve-static does not require a Next.js server to operate, making it more efficient and faster by eliminating background processes, such as file change monitoring.

To utilize the serve-static target for testing, run the following command:

nx serve-static my-next-app-e2e

This command performs several actions:

  1. It will build the Next.js application and generate the static HTML files.
  2. It will serve the static HTML files using a simple HTTP server.
  3. It will run the Cypress tests against the served static HTML files.

Deploying Next.js Applications

Once you are ready to deploy your Next.js application, you have absolute freedom to choose any hosting provider that fits your needs.

You may know that the company behind Next.js, Vercel, has a great hosting platform offering that is developed in tandem with Next.js itself to offer a great overall developer and user experience. We have detailed how to deploy your Next.js application to Vercel in a separate guide.

More Documentation

Here are other resources that you may find useful to learn more about Next.js and Nx.

Package reference

Here is a list of all the executors and generators available from this package.

Guides

Executors

  • build

    Build a Next.js application.

  • server

    Serve a Next.js application.

  • export

    Export a Next.js application. The exported application is located at dist/$outputPath/exported.

Generators