In a package-based
next.js project based on nx.js, I encountered the following error:
next-i18next was unable to find a user config at /var/task/next-i18next.config.js
The project directory structure is as follows:
.
├── dist # packages/web build output dir
├── nx.json
├── package-lock.json
├── package.json
├── packages
├── hooks # hooks library
├── icons # icons library
├── web # next.js web app
├── babel.config.json
├── configs
├── next-env.d.ts
├── next-i18next.config.js
├── next.config.js
├── package.json
├── pages
├── project.json
├── public
├── styles
├── theme
├── tsconfig.json
├── scripts
└── tsconfig.base.json
- nx.js: 15.8.9
- next.js: 13.1.1
- node: 18.12.1
The scripts section in the package.json file in the root directory is as follows:
{
"scripts": {
"dev": "nx run web:serve --development --verbose",
"build": "nx run web:build --production --verbose && node ./scripts/copyFiles.js"
}
}
The project.json file for the web application in nx is configured as follows:
{
"name": "web",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/web",
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/next:build",
"outputs": [
"{options.outputPath}"
],
"defaultConfiguration": "production",
"options": {
"root": "packages/web"
},
"configurations": {
"development": {
"outputPath": "dist/web"
},
"production": {
"outputPath": "dist/web"
},
"staging": {
"outputPath": "dist/web"
},
"beta": {
"outputPath": "dist/web"
}
}
},
"export": {
"executor": "@nrwl/next:export",
"options": {
"buildTarget": "web:build:production"
}
}
}
}
next-i18next.config.js
:
const configs = require('./configs');
const locales = Object.keys(configs.languages);
const path = require('path');
const isDev = process.env.NODE_ENV === 'development';
const isProd = process.env.NODE_ENV === 'production';
const getLocalePath = () => {
if (isProd) {
return path.resolve('./public/locales');
}
if (isDev) {
return configs.isServer
? require('path').resolve('./packages/web/public/locales')
: '/locales';
}
return path.resolve('./public/locales');
};
module.exports = {
// debug: isDev,
i18n: {
localeDetection: false,
defaultLocale: 'en',
locales,
},
defaultNS: 'common',
lowerCaseLng: true,
localePath: getLocalePath(),
nsSeparator: '::',
keySeparator: '::',
reloadOnPrerender: true,
// Do not load a fallbakick. We'll just use the key as the fallback.
fallbackLng: false,
// Empty strings should be invalid, so we can fallback to the message key
returnEmptyString: false,
};
next.config.js:
const {withNx} = require('@nrwl/next/plugins/with-nx');
process.env.I18NEXT_DEFAULT_CONFIG_PATH = `${__dirname}/next-i18next.config.js`;
const {i18n} = require('./next-i18next.config');
const path = require('path');
const configs = require('./configs');
/**
* @type {import('@nrwl/next/plugins/with-nx').WithNxOptions}
**/
const nextConfig = {
i18n,
nx: {
svgr: false,
},
rewrites: async () => [
{
source: '/api/:path*',
destination: `${configs.env.endpoints.baseAPI}/api/:path*`, // Proxy to Backend
},
],
transpilePackages: ['@crownbit/icons'],
experimental: {
largePageDataBytes: 1000 * 1000,
},
useFileSystemPublicRoutes: true,
reactStrictMode: true,
env: {
MOON_ENV: process.env.NX_MOON_ENV,
LATEST_GIT_HASH: process.env.LATEST_GIT_HASH,
},
sentry: {},
};
const {withSentryConfig} = require('@sentry/nextjs');
async function withCustom(phase) {
const nxConfig = withNx(nextConfig);
const c = await nxConfig(phase);
return withSentryConfig(
c,
{
silent: true,
project: 'javascript-nextjs',
},
{
widenClientFileUpload: true,
transpileClientSDK: true,
tunnelRoute: '/monitoring',
hideSourceMaps: true,
disableLogger: true,
},
);
}
module.exports = withCustom;
Because nx cannot output the build files in the source directory, the output directory for the web project is set to the
dist directory in the root directory. However, nx does not copy the next-i18next.config.js and configs directories to
the dist directory. Therefore, I wrote a script to copy the next-i18next.config.js and configs directories to the dist
directory:
const fs = require('fs-extra');
function copyFileOrDirectory(source, destination) {
try {
fs.copySync(source, destination);
console.log(`${source} Copy successful!`);
} catch (err) {
console.error(`${source} Copy failed:`, err);
}
}
console.log('Preparing to copy file or directory');
copyFileOrDirectory('./packages/web/configs', './dist/web/configs');
copyFileOrDirectory(
'./packages/web/next-i18next.config.js',
'./dist/web/next-i18next.config.js',
);
process.exit(0);
This script works correctly on the local development environment and self-managed servers. However, when deploying to Netlify, I encountered the following error:
next-i18next was unable to find a user config at /var/task/next-i18next.config.js
Does anyone know about this issue? Are there any recommended solutions?