Summary: since css-loader 6.0.0, my app no longer imports and displays web fonts correctly.
Mac OS Big Sur version 11.3.114.15.06.14.85.47.06.0.0 up to 6.2.0Imported fonts load and display correctly.
Imported fonts don't display, and browsers give me these errors. In Chrome:

and Firefox:

My app is an open-source repository: react-ui-library. The master branch is still using css-loader 5x (just bump it to 6x to reproduce).
I will give a summary of the code parts I think are relevant here.
src/style/fonts.less:
@font-face {
font-family: 'Lato';
font-weight: normal;
font-style: normal;
src: url('./fonts/lato/Lato-Regular.woff2') format('woff2');
}
webpack/webpack.common.rules.less:
{
test: /\.(ttf|eot|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
name: './fonts/[name].[contenthash].[ext]',
},
},
],
},
{
test: /^(?!.*?(\.module)).*\.less$/, //all *.less except for *.module.less
use: [
styleLoader,
{
loader: 'css-loader',
options: {
sourceMap: env === 'development',
},
},
'less-loader',
],
},
Check out the repository master branch. Bump the css-loader version 6x. Then npm install and npm run dev:docs to run the app. The errors can be seen in the console.
@mtmacdonald Glad it’s not just me! I’ve run into this on two separate projects after upgrading to v6.
One is a WordPress site built on top of the Sage theme framework (v9, using Webpack). Here’s their default Webpack config: https://github.com/roots/sage/blob/a3055a4469727c2becaacbb8612f9f49d9a670ee/resources/assets/build/webpack.config.js#L62-L120
The other site is built with Eleventy, using this boilerplate’s Webpack config:
https://github.com/clenemt/eleventy-webpack/blob/master/webpack.config.js
FWIW after upgrading to v6, any fonts referenced via @font-face in my CSS are renamed using just a hash and are copied to the assets root directory. This did not happen with v5.
Before:
@font-face {
font-family: "Zilla Slab";
font-style: normal;
font-weight: 400;
src: url("../fonts/zilla-slab/zilla-slab-regular.woff2") format("woff2"),
url("../fonts/zilla-slab/zilla-slab-regular.woff") format("woff");
}
After
@font-face {
font-family: "Zilla Slab";
font-style: normal;
font-weight: 400;
src: url(/assets/11cf47d98920cdfba843.woff2) format("woff2"),
url(/assets/8b7198a7b0b7f94ddc05.woff) format("woff"); }
Interestingly, I tried adding type: 'asset/resource', to my config (docs) but not only did that not fix it, it also caused the _same_ font issue in v5. I don’t know enough about how css-loader and Webpack work to know what this means but I hope it helps someone else figure out what’s going on!
Having exactly the same issue.
Was basically loosing my mind about this
Hi!
@mtmacdonald @tedw @xiCO2k
I ran into the same problem today, but there is a solution.
There is this issue: https://github.com/webpack-contrib/css-loader/issues/1337 which is similar but about images. And in there it is specified that both url-loader and file-loader are deprecated and people should migrate to using asset modules (Documentation can be found here: https://webpack.js.org/guides/asset-modules/)
This information is also mentioned in the release notes for v6.0.0 (https://github.com/webpack-contrib/css-loader/releases/tag/v6.0.0)
This is what I had before in my config:
{
test: [/\.(woff|eot|mp4)$/, /favicon-16x16\.png$/],
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
]
}
This is how my new configuration looks like (and works):
{
test: [/\.(woff|eot|mp4)$/, /favicon-16x16\.png$/],
type: 'asset/resource',
generator: {
filename: '[name][ext]'
}
}
Hope that helps.
And an example that was using url-loader with custom limit:
Old config:
{
test: /specific-filename\.svg$/,
use: [
{
// convert to data: URLs if less than 10,000 bytes
loader: 'url-loader',
options: {
limit: 10000,
fallback: {
loader: 'file-loader',
options: {
name: '[name]-[contenthash:8].[ext]'
}
}
}
}
]
}
New config:
{
test: /specific-filename\.svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000
}
},
generator: {
filename: '[name]-[contenthash:8][ext]'
}
}
Hey @MGafitescu
Will try it out.
Thanks for the help.
@MGafitescu Thanks so much, that did the trick!! I’d seen the part about file-loader and url-loader being deprecated but since it wasn’t in the “breaking changes” section I assumed they would still work for the time being.
FYI for everyone else upgrading to v6, note that the dot is automatically included with [ext] now (release notes). I overlooked this at first and was getting 404 errors since the filenames didn’t match (it’s correct in @MGafitescu’s code above).
- name: '[name].[ext]'
+ filename: '[name][ext]'
Thanks @MGafitescu it worked 100%
@tedw I think it wasn't in the breaking changes because you can still make them work.
I saw the following in the documentation:
When using the old assets loaders (i.e. file-loader/url-loader/raw-loader) along with Asset Module in webpack 5, you might want to stop Asset Module from processing your assets again as that would result in asset duplication. This can be done by setting asset's module type to 'javascript/auto'.
To be honest, I didn't try to make it work because it's easy enough to stop using the deprecated loaders and you'd have to do it anyway in the future.
@MGafitescu super helpful, thank you. Your resolution works. If I was using a deprecated loader and the suggestion resolves the issue (does for me), I'm fine with this ticket being closed (I'll do that now).
Most helpful comment
Hi!
@mtmacdonald @tedw @xiCO2k
I ran into the same problem today, but there is a solution.
There is this issue: https://github.com/webpack-contrib/css-loader/issues/1337 which is similar but about images. And in there it is specified that both
url-loaderandfile-loaderare deprecated and people should migrate to usingasset modules(Documentation can be found here: https://webpack.js.org/guides/asset-modules/)This information is also mentioned in the release notes for v6.0.0 (https://github.com/webpack-contrib/css-loader/releases/tag/v6.0.0)
This is what I had before in my config:
This is how my new configuration looks like (and works):
Hope that helps.