Webpack "OTS parsing error" font download

My webpack configuration indicates 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 configuration are as follows:

 { 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]"', } ], }, } 

This does not happen in Safari, and I have not tried Firefox.

In development, I serve files through webpack-dev-server ; during production, they are written to disk and copied to S3; in both cases, I get the same behavior in Chrome.

This also happens with large images (greater than the 10 kB limit in the image loader configuration).

+55
css fonts webpack
Dec 07 '15 at 12:41
source share
10 answers

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.

Embedded CSS screenshot in Chrome DevTools 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!

Relative URLs created by Webpack 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:

enter image description here 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.

+132
Dec 07 '15 at 12:41
source share

As pointed out by @mcortesi here , if you remove the source files from the css loader request, css will be built without using blob, and the data URLs will be parsed in order

+13
Dec 22 '15 at 15:46
source share

For me, the problem was the expression of my expression. The following is a trick to make the bootloader work:

 { test: /\.(woff|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/, loader: 'url-loader?limit=100000' }, 
+12
Nov 06 '16 at 2:05
source share

As with @ user3006381 above, my problem was not only the relative URLs, but the web package was placing the files as if they were javascript files. Their content was mainly:

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

in the font directory instead of real fonts, and the font files were in the output folder by hash codes. To fix this, I had to change the test on my bootloader (in my case on my GPU) so as not to load the font folder. I still had to set output.publicPath to webpack.config.js, as @ will-madden points out in his excellent answer.

+4
Apr 08 '16 at 22:49 on
source share

I had the same problem, but for different reasons.

After Will Madden's solution, this did not help, I tried all the alternative fixes that I could find through Intertubes - also to no avail. Studying further, I just managed to open one of the font files. The original contents of the file were somehow rewritten by Webpack in order to include some configuration information, most likely from a previous enumeration with the file loader. I replaced the damaged files with the originals, and voilร , the errors disappeared (for both Chrome and Firefox).

+2
Mar 28 '16 at 2:10
source share

I know this does not answer the exact OPs question, but I came here with the same symptom, but for a different reason:

I had .scss Slick Slider files included like this:

 @import "../../../node_modules/slick-carousel/slick/slick.scss"; 

Upon closer inspection, it turned out that he was trying to download the font from an invalid location ( <host>/assets/css/fonts/slick.woff ), as it was referencing a stylesheet.

I ended up just copying /font/ to my assets/css/ and the problem was solved for me.

+1
Jul 14 '17 at 12:09 on
source share

Since you are using url-loader :

The url loader acts as a file loader, but can return DataURL if the file is less than the byte limit.

Thus, another solution to this problem would be to make the restriction high enough so that the font files are included as DataURL, for example, up to 100000 which are larger or smaller than 100Kb :

 { 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: /\.woff(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=100000&mimetype=application/font-woff', }, { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=100000&mimetype=application/font-woff', }, { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=100000&mimetype=application/octet-stream', }, { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, use: 'file-loader', }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: 'url-loader?limit=100000&mimetype=image/svg+xml', }, ], }, } 

Always considering what constitutes a limit number:

Byte limit for embedded files as data URL

This way you do not need to provide the entire asset url. Which can be tricky if you want Webpack to respond not only with localhost.

One more note: this configuration is NOT RECOMMENDED for production. This is just for ease of development.

+1
Jan 04 '18 at 11:03
source share

If you are using Angular , you need to check that your

 <base href="/"> 
Tag

fits your style list. I switched my code:

  <script src="~/bundles/style.bundle.js"></script> <base href="~/" /> 

:

  <base href="~/" /> <script src="~/bundles/style.bundle.js"></script> 

and the problem has been fixed. Thanks to this post for opening my eyes.

0
Mar 13 '17 at 15:38
source share

As of 2018

use MiniCssExtractPlugin

for webpack (> 4.0) will solve this problem.

https://github.com/webpack-contrib/mini-css-extract-plugin

Using extract-text-webpack-plugin in the accepted answer is NOT recommended for Webpack 4. 0+.

0
Aug 02 '18 at 10:07
source share

The best and easiest way is to encode the font file in base64. And use it in the font. To encode, go to the folder with the font file and use the command in the terminal:

 base64 Roboto.ttf > basecodedtext.txt 

You will get an output file called basecodedtext.txt. Open this file. Remove all spaces in this.

Copy this code and add the following line to the CSS file:

 @font-face { font-family: "font-name"; src: url(data:application/x-font-woff;charset=utf-8;base64,<<paste your code here>>) format('woff'); } 

Then you can use font-family: "font-name" in your CSS.

0
May 15 '19 at 13:50
source share



All Articles