TL; DR Use absolute paths to your assets (including the fully qualified host name) by setting output.publicPath , for example. " http://example.com/assets/ ".
Problem
The problem is how URLs resolve to Chrome when they are parsed from a dynamically loaded CSS block.
When you load the page, the browser loads your JavaScript file with the description of the Webpack package, which (when you use the style-loader ) also contains a Base64-encoded copy of your CSS, which is loaded onto the page.
This is how it looks in Chrome DevTools
This is great for all images or fonts that are encoded in CSS as data URIs (i.e. the contents of the file are embedded in CSS), but for the assets that the URL refers to, the browser needs to find and extract the file.
Now, by default, file-loader (which url-loader delegates to large files) will use relative URLs to refer to assets - and what a problem!
These are the default URLs created by file-loader - relative URLs
When you use relative URLs, Chrome will resolve them relative to the containing CSS file. This is usually normal, but in this case the containing file is in blob://... and any relative URLs are referenced the same way. The end result is that Chrome tries to download them from the parent HTML file and ultimately tries to parse the HTML file as the contents of the font, which obviously won't work.
Decision
Force file-loader use absolute paths, including protocol ("http" or "https").
Modify your webpack configuration to include something equivalent:
{ output: { publicPath: "http://localhost:8080/", // Development Server // publicPath: "http://example.com/", // Production Server } }
Now the URLs it creates will look like this:
Absolute URLs!
These URLs will be correctly parsed by the Chrome browser and any other browser.
Using extract-text-webpack-plugin
It is worth noting that if you extract the CSS into a separate file, you will not have this problem, because your CSS will be in the correct file and the URLs will be resolved correctly.