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});
12This 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.
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);
21If 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);
8This 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);
6Manually 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 updatedConfig = require('@sentry/nextjs')(updatedConfig, { silent: true });
25
26 return updatedConfig;
27};
28