Webpack "OTS parsing error" loading fonts

109,089

Solution 1

TL;DR Use absolute paths to your assets (including your complete hostname) by setting your output.publicPath to e.g. "http://example.com/assets/".

The problem

The problem is the way that URLs are resolved by Chrome when they're parsed from a dynamically loaded CSS blob.

When you load the page, the browser loads your Webpack bundle entry JavaScript file, which (when you're using the style-loader) also contains a Base64 encoded copy of your CSS, which gets loaded into the page.

Screenshot of embedded CSS in Chrome DevTools This is what it looks like in Chrome DevTools

That's fine for all the images or fonts which are encoded into the CSS as data URIs (i.e. the content of the file is embedded in the CSS), but for assets referenced by URL, the browser has to find and fetch the file.

Now by default the file-loader (which url-loader delegates to for large files) will use relative URLs to reference assets - and that's the problem!

Relative URLs generated by Webpack These are the URLs generated by file-loader by default - relative URLs

When you use relative URLs, Chrome will resolve them relative to the containing CSS file. Ordinarily that's fine, but in this case the containing file is at blob://... and any relative URLs are referenced the same way. The end result is that Chrome attempts to load them from the parent HTML file, and ends up trying to parse the HTML file as the content of the font, which obviously won't work.

The Solution

Force the file-loader to use absolute paths including the protocol ("http" or "https").

Change your webpack config to include something equivalent to:

{
  output: {
    publicPath: "http://localhost:8080/", // Development Server
    // publicPath: "http://example.com/", // Production Server
  }
}

Now the URLs that it generates will look like this:

enter image description here Absolute URLs!

These URLs will be correctly parsed by Chrome and every other browser.

Using extract-text-webpack-plugin

It's worth noting that if you're extracting your CSS to a separate file, you won't have this problem because your CSS will be in a proper file and URLs will be correctly resolved.

Solution 2

For me the problem was my regex expression. The below did the trick to get bootstrap working:

{
    test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
    loader: 'url-loader?limit=100000'
},

Solution 3

As asnwered here by @mcortesi if you remove the sourceMaps from the css loader query the css will be built without use of blob and the data urls will be parsed fine

Solution 4

As with @user3006381 above, my issue was not just relative URLs but that webpack was placing the files as if they were javascript files. Their contents were all basically:

module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";

in the fonts directory instead of the real fonts and the font files were in the output folder under hash codes. To fix this, I had to change the test on my url-loader (in my case my image processor) to not load the fonts folder. I still had to set output.publicPath in webpack.config.js as @will-madden notes in his excellent answer.

Solution 5

I experienced the same problem, but for different reasons.

After Will Madden's solution didn't help, I tried every alternative fix I could find via the Intertubes - also to no avail. Exploring further, I just happened to open up one of the font files at issue. The original content of the file had somehow been overwritten by Webpack to include some kind of configuration info, likely from previous tinkering with the file-loader. I replaced the corrupted files with the originals, and voilà, the errors disappeared (for both Chrome and Firefox).

Share:
109,089
Will Madden
Author by

Will Madden

Updated on July 08, 2022

Comments

  • Will Madden
    Will Madden almost 2 years

    My webpack config specifies that fonts should be loaded using url-loader, and when I try to view the page using Chrome I get the following error:

    OTS parsing error: invalid version tag
    Failed to decode downloaded font: [My local URL]
    

    The relevant parts of my config look like this:

    {
      module: {
        loaders: [
          // ...
          {
            test: /\.scss$/,
            loaders: ['style', 'css?sourceMap', 'autoprefixer', 'sass?sourceMap'],
          },
          {
            test: /images\/.*\.(png|jpg|svg|gif)$/,
            loader: 'url-loader?limit=10000&name="[name]-[hash].[ext]"',
          },
          {
            test: /fonts\/.*\.(woff|woff2|eot|ttf|svg)$/,
            loader: 'file-loader?name="[name]-[hash].[ext]"',
          }
        ],
      },
    }
    

    It doesn't happen in Safari, and I haven't tried Firefox.

    In development I'm serving files through webpack-dev-server, in production they're written to disk and copied to S3; in both cases I get the same behaviour in Chrome.

    This also happens to larger images (greater than the 10kB limit in the image loader config).