Everybody knows how to set up a favicon.ico link in HTML:
Killer Solution in 2020
This solution necessarily comes nine years after the question was originally asked, because, until fairly recently, most browsers have not been able to handle favicons in .svg
format.
That's not the case anymore.
See: https://caniuse.com/#feat=link-icon-svg
Right now, in June 2020, these browsers can handle SVG Favicons:
Note that these browsers still can't:
With the above in mind, we can now use SVG Favicons with a reasonable degree of confidence.
The main objective here is to avoid HTTP Requests.
As other solutions on this page have mentioned, a pretty smart way to do this is to use a Data URI rather than an HTTP URL.
SVGs (especially small SVGs) lend themselves perfectly to Data URIs, because the latter is simply plaintext (with any potentially ambiguous characters percentage-encoded) and the former, being XML, can be written out as a long line of plaintext (with a smattering of percentage codes) incredibly straightforwardly.
In December 2019, Leandro Linares was one of the first to realise that since Chrome had joined Firefox in supporting SVG Favicons, it was worth experimenting to see if a favicon could be created out of an emoji:
https://lean8086.com/articles/using-an-emoji-as-favicon-with-svg/
Linares' hunch was right.
Several months later (March 2020), Code Pirate Lea Verou realised the same thing:
https://twitter.com/leaverou/status/1241619866475474946
And favicons were never the same again.
Here's a simple SVG:
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16">
<text x="0" y="14">
I found an interesting solution on this page. It is german but you will be able to understand the code.
You put the base64 data of the icon into an external stylesheet, so it will be cached. In the head of your website you have to define the favicon with an id and the favicon is set as a background-image
in the stylesheet for that id.
link#icon {
background-image:url("data:image/x-icon;base64,<base64_image_data>");
}
and the html
<html>
<head>
<link id="icon" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="/styles.css" />
...
</head>
<body>
...
</body>
</html>
It's a great idea, but if Google hasn't done it on their homepage, I'm betting it can't (currently) be done.
A minor improvement to @yc's answer is injecting the base64-encoded favicon from a JavaScript file that would normally be used and cached anyway, and also suppressing the standard browser behavior of requesting favicon.ico
by feeding it a data URI in the relevant meta
tag.
This technique avoids the extra http request and is confirmed to work in recent versions of Chrome, Firefox and Opera on Windows 7. However it doesn't appear to work in Internet Explorer 9 at least.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Suppress browser request for favicon.ico -->
<link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
<script src="script.js"></script>
...
script.js
var favIcon = "\
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABrUlEQVR42mNkwAOepOgxMTD9mwhk\
[...truncated for brevity...]
IALgNIBUQBUDAFi2whGNUZ3eAAAAAElFTkSuQmCC";
var docHead = document.getElementsByTagName('head')[0];
var newLink = document.createElement('link');
newLink.rel = 'shortcut icon';
newLink.href = 'data:image/png;base64,'+favIcon;
docHead.appendChild(newLink);
/* Other JS would normally be in here too. */
The proper solution is to use HTTP pipelining.
HTTP pipelining is a technique in which multiple HTTP requests are written out to a single socket without waiting for the corresponding responses. Pipelining is only supported in HTTP/1.1, not in 1.0.
It's required that servers support it, but not necessarily partipate.
HTTP pipelining requires both the client and the server to support it. HTTP/1.1 conforming servers are required to support pipelining. This does not mean that servers are required to pipeline responses, but that they are required not to fail if a client chooses to pipeline requests.
Many browser clients don't do it, when they should.
HTTP pipelining is disabled in most browsers.
- Opera has pipelining enabled by default. It uses heuristics to control the level of pipelining employed depending on the connected server.
- Internet Explorer 8 does not pipeline requests, due to concerns regarding buggy proxies and head-of-line blocking.
- Mozilla browsers (such as Mozilla Firefox, SeaMonkey and Camino), support pipelining however it is disabled by default. It uses some heuristics, especially to turn pipelining off for IIS servers.
- Konqueror 2.0 supports pipelining, but it's disabled by default.[citation needed]
- Google Chrome does not support pipelining.
I would recommend you try enabling pipelining in Firefox and try it there, or just use Opera (shudder).
Does it really matter?
Many browsers load the favicon as a low priority so that it doesn't block the page load in anyway, so yes it's an extra request but it's not on any critical path.
The accepted solution is horrible as until the JS has been retrieved and executed all the DOM elements below will be blocked from rendering and it doesn't reduce the number of requests!