I am installed a module in my project that includes a <img />
tag within it, and next.js is unable to properly render the image. Currently, the image in the module is being displayed as follows:
<img src="[Object Object]" />
I think this issue may exist after version 11 of Next.js. I am using Next.js version 14. In Next.js version 14, most aspects work smoothly without any issues. However, there is a problem with rendering images that are located in the installed node_modules.
In my opinion, this issue occurs because of the use of the next.js webpack loader, which imports the image module in the following format:
export interface StaticImageData {
src: string;
height: number;
width: number;
blurDataURL?: string;
blurWidth?: number;
blurHeight?: number;
}
declare module '*.png' {
const content: import('../dist/shared/lib/image-external').StaticImageData
export default content
}
I attempted to use the next-images
package but unfortunately, I was unable to solve the issue or problem I was facing.
I finally realized that Next.js uses the next-image-loader
as the image loader in Webpack, based on the configuration found in the Next.js repository at this link.
{
test: nextImageLoaderRegex,
loader: 'next-image-loader',
issuer: { not: regexLikeCss },
dependency: { not: ['url'] },
resourceQuery: {
not: [
new RegExp(WEBPACK_RESOURCE_QUERIES.metadata),
new RegExp(WEBPACK_RESOURCE_QUERIES.metadataRoute),
new RegExp(WEBPACK_RESOURCE_QUERIES.metadataImageMeta),
],
},
options: {
isDev: dev,
compilerType,
basePath: config.basePath,
assetPrefix: config.assetPrefix,
},
}
In order to address the compatibility issue with next-image-loader
, I excluded it for the specific node_module
and opted instead to use the asset module of webpack to load images within the installed package. I achieved this by combining the image loader of create-react-app
webpack configurations and Next.js webpack image loader. You can find the Webpack image loader configuration of Create React App's react-scripts package at this link.
next.config.js
to load all images/** @type {import('next').NextConfig} */
const path = require("path")
const IMAGE_INLINE_SIZE_LIMIT = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10240'
);
const NEXT_IMAGE_LOADER_EXCLUDE = ['SPECIFIC_NODE_MODULE_NAME'].map((module) => {
return path.resolve(__dirname, `node_modules/${module}`);
})
module.exports = {
webpack(config) {
const nextImageLoaderIndex = config.module.rules.findIndex(item => item.loader === "next-image-loader");
const { loader, options, ...ruleProps } = config.module.rules[nextImageLoaderIndex];
config.module.rules[nextImageLoaderIndex] = {
...ruleProps,
oneOf: [
{
exclude: NEXT_IMAGE_LOADER_EXCLUDE,
loader,
options,
},
{
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: IMAGE_INLINE_SIZE_LIMIT,
},
},
}
]
};
return config
}
}
If there is a better way to solve this problem, please mention it.