Update: Read my other comments below for a more pinpointed problem.
I tried to set a background image in a SCSS module with background: url("./footer-region-bg.jpg") repeat;
(is in the same directory as the component). But this results in the following when fetching the image.
This was working with @zeit/next-sass
, but it doesn't with the native scss modules.
Load an Image from the same directory as the component in an SCSS module like mentioned above. Use the native SCSS modules from NextJs.
The image should be loaded correctly
Sone new things I tried:
Didn't work:
.next
directoryWhat worked:
I will now check why it works in a new project but not in my project
Alright, after some more testing I found something interesting. The problem can be reproduced when using the next-images
package. My current next.config.js
looks like this:
const withImages = require("next-images");
module.exports = withImages({
poweredByHeader: false // This doesn't really matter
});
For some reason this config breaks the SCSS/CSS module images resolver.
Update: The same is true for the https://www.npmjs.com/package/next-optimized-images
package.
same for me
Same here.
When I remove my url-loader
related code in next.config.js
, background-image
works fine.
There's my code :
// next.config.js
// ....
config.module.rules.push(
{
test: /\.(jpg|png|gif|ico)$/,
use: [
{
loader: "url-loader"
}
]
}
);
// ...
I'm not sure if it is a next-images
issue or the Next.js itself.
I faced the same issue after upgrading from 9.1.7
to 9.3.1
. I was using next-sass
and url-loader
with the custom webpack config.
By using the built-in Sass feature, background and font face url()
s inside .scss
files stop working. After digging into Next.js files I realized that it handles url()
imports through the file-loader
now.
I hadn't used the built-in CSS feature before and that is why I hadn't faced the issue.
I ended up with excluding the url()
file imports by setting a test regex in webpack issuer
config as follows:
// next.config.js
module.exports = {
// ...
webpack: (config) => {
config.module.rules.push({
issuer: {
// nextjs already handles url() in css/sass/scss files
test: /\.\w+(?<!(s?c|sa)ss)$/i,
},
test: /\.(jpg|gif|png|svg|ico)$/i,
use: [
{
loader: 'url-loader',
options: {
// sample options
limit: 8192,
outputPath: '...',
context: 'src',
name: '[path][name].[hash:8].[ext]',
publicPath: `your/public/path`,
},
},
],
});
return config;
},
// ...
};
Hope this helps.
I'm not sure if it is a
next-images
issue or the Next.js itself.I faced the same issue after upgrading from
9.1.7
to9.3.1
. I was usingnext-sass
andurl-loader
with the custom webpack config.By using the built-in Sass feature, background and font face
url()
s inside.scss
files stop working. After digging into Next.js files I realized that it handlesurl()
imports through thefile-loader
now.I hadn't used the built-in CSS feature before and that is why I hadn't faced the issue.
Workaround
I ended up with excluding the
url()
file imports by setting a test regex in webpackissuer
config as follows:// next.config.js module.exports = { // ... webpack: (config) => { config.module.rules.push({ issuer: { // nextjs already handles url() in css/sass/scss files test: /\.\w+(?<!(s?c|sa)ss)$/i, }, test: /\.(jpg|gif|png|svg|ico)$/i, use: [ { loader: 'url-loader', options: { // sample options limit: 8192, outputPath: '...', context: 'src', name: '[path][name].[hash:8].[ext]', publicPath: `your/public/path`, }, }, ], }); return config; }, // ... };
Hope this helps.
Works perfectly. I looked in the source code of the next-images
and it basically includes a url-loader
with a predefined configuration for you. I created an issue in their repository and I think that your fix should work there.
This is a bug with the next-images
package(s), please file them upstream.
tl;dr the new CSS support does not require next-images
, so next-images
needs to be sure to only apply to JS files. There could be an option to "force on" for CSS files for legacy use cases.
Thanks guys for reporting this issue. I'll fix that in the next-images
package today and will release a new patch for that.
@Timer Thank you. As an aside, it would be great if we can choose between file-loader
and url-loader
for url()
s inside CSS/Sass files (or even setting the options, perhaps in the next.config.js
?) to take advantage of the Data-URI thing.
@theshem Can you open a new issue proposing to add support for data URIs OOTB?
One thing to note, using data URIs are not generally a safe default because it's incompatible with SVG sprite systems, for example.
If we were to use data URIs out of the box (for small assets), SVGs would need to be excluded:
https://css-tricks.com/svg-fragment-identifiers-work/
for reference: https://github.com/twopluszero/next-images/issues/31
Thanks to @theshem, this issue is solved now in next-images
.
Closing as it was solved upstream. Thanks everyone!
The "fix" here appears to be mostly a workaround though. It would be nice if Next detected the use of image processing plugins like next-images
or next-optimized-images
, particularly the latter. Right now there's a working workaround for next-optimized-images
but it doesn't allow you to run images imported in SCSS through i.e. optipng
etc.
This might still be an upstream issue (some way to tie into Next's handling of images to apply optimizations?) but it seems like there's precedent here for the "detect and disable" functionality for handling images since that's what happens right now i.e. if you're using next-sass
. From the official 9.3 blog post:
This new feature is fully backwards compatible. If you are using @zeit/next-sass or other CSS related plugins the feature is disabled to avoid conflicts.
I realize this issue mentions next-images
specifically in the title, let me know if I should open a new issue instead.
The "fix" doesn't solve importing images into js files through template literals.
Given the src/styles/index.module.css
file:
.test::before {
content: url("./images/image.jpg");
}
no next.config.js
src/pages/index.js
:
import styles from "../styles/index.module.css";
export default function IndexPage() {
return (
<div>
{/* this works */}
<div className={styles.test}></div>
{/* this doesn't work */}
<div><img src={require('../styles/images/image.jpg')} /></div>
{/* this doesn't work */}
<div>{["image.jpg"].map((src) => (<img key={src} src={require(`../styles/images/${src}`)} />))}</div>
</div>
);
}
next.config.js
:
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.(png|gif|jpg|jpeg)(\?|$)/,
use: [
{
loader: "file-loader",
options: {
publicPath: `/_next/static/media/`,
outputPath: `${options.isServer ? "../" : ""}static/media/`,
name: "[name].[hash].[ext]",
},
},
],
});
return config;
},
};
src/pages/index.js
:
import styles from "../styles/index.module.css";
export default function IndexPage() {
return (
<div>
{/* this doesn't work */}
<div className={styles.test}></div>
{/* this works */}
<div><img src={require('../styles/images/image.jpg')} /></div>
{/* this works */}
<div>{["image.jpg"].map((src) => (<img key={src} src={require(`../styles/images/${src}`)} />))}</div>
</div>
);
}
next.config.js
:
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.(png|gif|jpg|jpeg)(\?|$)/,
issuer: {
exclude: /\.(css|sass|scss)$/i,
},
use: [
{
loader: "file-loader",
options: {
publicPath: `/_next/static/media/`,
outputPath: `${options.isServer ? "../" : ""}static/media/`,
name: "[name].[hash].[ext]",
},
},
],
});
return config;
},
};
src/pages/index.js
:
import styles from "../styles/index.module.css";
export default function IndexPage() {
return (
<div>
{/* this works */}
<div className={styles.test}></div>
{/* this works */}
<div><img src={require('../styles/images/image.jpg')} /></div>
{/* this doesn't work */}
<div>{["image.jpg"].map((src) => (<img key={src} src={require(`../styles/images/${src}`)} />))}</div>
</div>
);
}
So what should I do to get all three this works
together ?
Most helpful comment
I'm not sure if it is a
next-images
issue or the Next.js itself.I faced the same issue after upgrading from
9.1.7
to9.3.1
. I was usingnext-sass
andurl-loader
with the custom webpack config.By using the built-in Sass feature, background and font face
url()
s inside.scss
files stop working. After digging into Next.js files I realized that it handlesurl()
imports through thefile-loader
now.https://github.com/zeit/next.js/blob/v9.3.1/packages/next/build/webpack/config/blocks/css/index.ts#L278-L292
https://github.com/zeit/next.js/blob/v9.3.1/packages/next/build/webpack/config/blocks/css/index.ts#L17
I hadn't used the built-in CSS feature before and that is why I hadn't faced the issue.
Workaround
I ended up with excluding the
url()
file imports by setting a test regex in webpackissuer
config as follows:Hope this helps.