Configuring Next.js plugins

Next.js plugins are configured in the project's next.config.js file. Nx adds a its own plugin (withNx) to help the Next.js application understand workspace libraries, and other Nx-specific features. See below for an example of the withNx plugin that Nx adds by default.

1// next.config.js 2 3// ... 4 5module.exports = withNx({ 6 // Nx configuration goes here 7 nx: { 8 svgr: false, 9 }, 10 // Add Next.js configuration goes here 11}); 12

This guide contains information on how to configure and compose the Nx plugin with other plugins, such as @next/mdx. Note that Nx prior to version 16 is missing the compose utility from the @nx/next package, and a workaround will be provided for Nx 15 and prior.

Avoid next-compose-plugins

There is a popular package called next-compose-plugins that has not been maintained for over two years. This package does not correctly combine plugins in all situations. If you do use it, replace the package with Nx 16's composePlugins utility (see below).

withNx plugin

The withNx Next.js plugin provides integration with Nx, including support for workspace libraries, SVGR, and more. It is included by default when you generate a Next.js application with Nx. When you customize your next.config.js file, make sure to include the withNx plugin.

Options

svgr

Type: boolean

Set this to true if you would like to to use SVGR. See: https://react-svgr.com/

babelUpwardRootMode

Type: boolean

For a monorepo, set to true to incorporate .babelrc files from individual libraries into the build. Note, however, that doing so will prevent the application's .babelrc settings from being applied to its libraries. It is generally recommended not to enable this option, as it can lead to a lack of consistency throughout the workspace. Instead, the application's .babelrc file should include the presets and plugins needed by its libraries directly. For more information on babel root-mode, see here: https://babeljs.io/docs/en/options#rootmode

Set this to true if you want .babelrc from libraries to be used in a monorepo. Note that setting this to true means the application's .babelrc will not apply to libraries, and it is recommended not to use this option as it may lead to inconsistency in the workspace. Instead, add babel presets/plugins required by libraries directly to the application's .babelrc file. See: https://babeljs.io/docs/en/options#rootmode

Composing plugins using composePlugins utility (Nx 16 and later)

Since Nx 16, we provide a composePlugins utility function that helps users combine multiple Next.js plugins together.

1// next.config.js 2const { composePlugins, withNx } = require('@nx/next'); 3/** 4 * @type {import('@nx/next/plugins/with-nx').WithNxOptions} 5 **/ 6const nextConfig = { 7 nx: { 8 // Set this to true if you would like to to use SVGR 9 // See: https://github.com/gregberge/svgr 10 svgr: false, 11 }, 12 // Add Next.js configuration here 13}; 14 15const plugins = [ 16 // Add more Next.js plugins to this list if needed. 17 withNx, 18]; 19 20module.exports = composePlugins(...plugins)(nextConfig); 21

If you want to add additional plugins, say @next/mdx, you can add it to the plugins list.

1const plugins = [ 2 // Add more Next.js plugins to this list if needed. 3 require('@next/mdx')(), 4 withNx, 5]; 6 7module.exports = composePlugins(...plugins)(nextConfig); 8

This the exported configuration will correctly call each plugin in order and apply their configuration changes to the final object. Note that composePlugins function will return an async function, so if you need to debug the configuration you can add a debug plugin as follows.

1module.exports = composePlugins(...plugins, function debug(config) { 2 // The debug plugin will be called last 3 console.log({ config }); 4 return config; 5})(nextConfig); 6

Manually composing plugins (Nx 15 and prior)

If you are not on Nx 16 and later versions, the composePlugins utility is not available. However, you can use the workaround below to use multiple plugins.

1// next.config.js 2 3// ... 4 5/** 6 * @type {import('@nx/next/plugins/with-nx').WithNxOptions} 7 **/ 8const nextConfig = { 9 // ... 10}; 11 12const plugins = [ 13 // Your plugins exlcuding withNx 14]; 15 16module.exports = async (phase, context) => { 17 let updatedConfig = plugins.reduce((acc, fn) => fn(acc), nextConfig); 18 19 // Apply the async function that `withNx` returns. 20 updatedConfig = await withNx(updatedConfig)(phase, context); 21 22 // If you have plugins that has to be added after Nx you can do that here. 23 // For example, Sentry needs to be added last. 24 const { withSentryConfig } = require('@sentry/nextjs'); 25 updatedConfig = withSentryConfig(updatedConfig); 26 27 return updatedConfig; 28}; 29