3

I want to cache my sites favicon, the same way I cache css/js/png on my site, e.g. with a expires header far in the future. However I can't see how to do this. All the articles that I find on favicon and angular, all suggest to just use a link in the html page, place the favicon.ico in assets, and copy using the assets builder option.

<link rel="icon" type="image/x-icon" href="favicon.ico">

This won't achieve what I want, as the file is called "favicon.ico". I want it to be called "favicon.[content hash].ico", in the same was that all js, css and png files are.

I found this article How to change Angular CLI favicon, and tried the faviconInitFactory method mentioned in one of the comments. I think that this is the "right" way to resolve this issue, but it won't work for me.

If I just use this line, then angular complains that it doesn't know how to load an ico file

const favicon = require('../assets/favicon.ico');


ERROR in ./src/assets/favicon.ico
Module parse failed: Unexpected character ' ' (1:0)
You may need an appropriate loader to handle this file type.

As an alternative, I tried to use an import like this

import favicon from '!raw-loader!../assets/favicon.ico';

I then used "custom-webpack:browser" and a webpack file

module.exports = {
  module: {
    rules: [
      {
        test: /\..ico$/,
        use: [
          {
            loader: 'file-loader',
          }
        ]
      }
    ]
  }
}

This gets me further, but when I run the app, and load the page, when I try to log them, with this

console.log(`setting favicon to ${favicon}`);

I get "setting favicon to " and then some unicode symbols. I take this to mean that the file has been binary loaded instead of base 64 inlined. I get that this is because the file's contents are small (6kb), so the loader is inlining them. However they are truly loaded as binary, instead of base64.

So to recap, I don't want to serve a file "favicon.ico", I want to serve one "favicon.[content hash].ico". The article shows how to dynamically refer to this file, but I can't see how to configure angular cli's loaders to load as base 64, or a url.

  • Why do you want to cache it when the browser, by default, is going to cache it anyway ? – Zze Jan 20 '19 at 21:12
  • 1
    As stated above, I want to have the same treatment for favicon as I do for all page resources, i.e. css, js & pngs i.e. browser fetches them once, and each has expires header set, so that they aren't fetched again. This works for css, js & pngs as they use content hashes, so I want the same treatment for favicon. – chrisderham Jan 21 '19 at 10:00

1 Answers1

0

Nobody has suggested an answer, and I haven't found one. The best that I could come up with was to manually perform the process, i.e. calculate the md5 of the icon, then update the page to look for this. If the icon changes, then we can change the name, and it just works.

CertUtil -hashfile .\favicon.ico MD5
MD5 hash of .\favicon.ico:
b9aa7c338693424aae99599bec875b5f

Then we rename the file to 'favicon.b9aa7c338693424aae99599bec875b5f.ico', and update the html page to reference it.

<link rel="icon" type="image/x-icon" href="favicon.b9aa7c338693424aae99599bec875b5f.ico">