Background
After switching a project from Sprockets to Webpack, I started observing a bug that was hard to debug: Our custom icon font could sometimes not be displayed until a full page reload.
Digging deeper the only difference before and after the page load was the encoding interpretation of the iconfont stylesheet:
Correct representation (UTF-8):
.icon:before {
content: ""
}
Broken representation (other charset):
.icon:before {
content: "ï„""
}
Other people have the same issue Show archive.org snapshot , it could be a bug in Chrome.
Now, according to MDN Show archive.org snapshot there are three non-obsolete ways to manually define the charset of a CSS file:
- The value of the Unicode byte-order character placed at the beginning of the file (BOM).
- The value given by the charset attribute of the Content-Type: HTTP header or the equivalent in the protocol used to serve the style sheet.
- The @charset CSS at-rule.
Sprockets
The asset pipeline (with Sprockets) does not seem to be affected by this issue, as every generated file includes a BOM.
The first rule above is fulfilled.
You can check if a file has a BOM with the file
command, e.g. file styles.css
should include the text "(with BOM)".
Webpack
Webpack does not include a BOM per default. Adding the unpopular library
webpack-utf8-bom
Show archive.org snapshot
to my project (production.js) solved the issue for me. Or at least, I did not encounter it again yet.
You might have to upgrade Webpack to version 5 for this approach.
Adding the @charset "UTF-8";
rule to my stylesheet seemed easier at first, but turned out to be very hard to archive outside the development environment. See the issue
@import invalidates @charset declaration
Show archive.org snapshot
for more context.
Using the Content-Type: charset=UTF-8
header might do the trick for you. I decided against it as it implied changing both manual and automatic rules for CSS files at the Load Balancer and CDN. Setting the charset globally to utf-8 may cause other issues as the original charset (e.g. UTF-16) is no longer respected.