mckinley.cc Home Blog Notes Twtxt

Defining a Favicon for a Bookmarklet

June 11th, 2022

Now that you know how to write a bookmarklet, how do you differentiate it from all your other bookmarks? A favicon, of course! Today, we're misusing the Netscape bookmarks file format to give a favicon to a bookmark that wouldn't normally have one, including this very website.

This post is the second in my series about bookmarklets. The other posts are linked below.

  1. An Acceptable Use for JavaScript
  2. Defining a Favicon for a Bookmarklet
  3. Bringing Back a Useful Browser Feature With a Bookmarklet

A favicon is a small icon that is used to identify a webpage. When you bookmark a page in your Web browser, it is usually displayed in bookmark lists with the favicon of the website. This helps differentiate it from others and gives a familiar visual indicator to identify it later. The favicon was first introduced to Internet Explorer 5.0 in 1999, and was later recognized in the HTML 4.01 specification. I write more about favicons and their history in my post Browsers: Please stop requesting /favicon.ico automatically.

Like the automatic requests for /favicon.ico, the Netscape bookmarks file is a terrible, diseased relic of the past. It has inexplicably become the de-facto standard for moving bookmarks across Web browsers and backing them up. Like many terrible, diseased, relic-of-the-past de-facto computing standards that we're all stuck with, there is no canonical specification. It's all up to the developers of the Web browsers that implement the format. Archive Team's file format wiki describes it as:

"(kinda, sorta) HTML, with a weird doctype specific to Netscape and some offenses against HTML decency like odd nesting of elements."

I couldn't come up with a better description than that. Rather than trying to explain it further, here's an example of one as exported from LibreWolf 101.0.

<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
     It will be read and overwritten.
     DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<meta http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'none'; img-src data: *; object-src 'none'"></meta>
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks Menu</H1>

<DL><p>
    <DT><H3 ADD_DATE="1647658820" LAST_MODIFIED="1654579204" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
    <DL><p>
        <DT><A HREF="https://mckinley.cc/" ADD_DATE="1654579204" LAST_MODIFIED="1654579204">Home - mckinley.cc</A>
        <DT><A HREF="https://twtxt.net/" ADD_DATE="1654579791" LAST_MODIFIED="1654579791" ICON_URI="https://twtxt.net/img/d46e50b3/favicon.png" ICON="data:image/png;base64,iVBOR[...]CYII=">twtxt.net Local timeline</A>
    </DL><p>
</DL>

That's not like any text/html I've ever seen. Documents ≠ programs, and document formats ≠ data serialization formats. Anyway, you see that ICON attribute? The one with the data: URI? It turns out that we can set that to whatever we want and the browser will go along with it. Using Microsoft's documentation of the format as used in Internet Explorer, I was able to create a much more clean bookmark file of my own. So, if you were to import this file, you would get a bookmark to my home page with a snazzy "m" icon even though my website doesn't have a favicon. (Download)

<!DOCTYPE NETSCAPE-Bookmark-file-1>
    <!-- This is an automatically generated file.
         It will be read and overwritten.
         DO NOT EDIT! -->
    <TITLE>Bookmarks</TITLE>
    <H1>Bookmarks Menu</H1>
    <DL>
        <DT><A HREF="https://mckinley.cc/" ICON="data:image/gif;base64,R0lGODlhEAAQAPIHAA4ODtmMBMmBBvigAemYA7h1CIRVCwAAACH5BAUAAAcALAAAAAAQABAAAAM7eAfczmq9Cam9OBQxRgCc9wRDYRidcA6CExDN2whw/DHCDRQ1E7Q4Hc8FBAl7gN/sSFw2hpioVDJVVBMAOw==">mckinley.cc</A>
    </DL>

This file works in Firefox and Chromium based browsers as of version 101. For Firefox based browsers, go to the bookmarks library (Menu > Bookmarks > Manage bookmarks or Ctrl+Shift+O) and select "Import and backup" > "Import Bookmarks from HTML". For Chromium based browsers, go to the bookmarks manager (Menu > Bookmarks > Bookmark manager, chrome://bookmarks, or Ctrl+Shift+O) and select "Import bookmarks" from the three-dot menu in the top right of the page.

From here, it's pretty simple to apply this to bookmarklets. Since they're just normal bookmarks that link to special javascript: URIs, we can add a favicon in the same way as before. I've gone ahead and done that for the three simple bookmarklets from the last post. You can download the file here.

I hope you found this post useful. When I was trying to figure out how to do this, I couldn't find much documentation on it in relation to bookmarklets. Granted, most of this post wasn't about bookmarklets either. Regardless, I think it's a neat trick.