datasette
datasette copied to clipboard
Ability to set a custom favicon
If you're running a website on Datasette, like https://www.niche-museums.com/ or https://til.simonwillison.net/ - you should have the ability to easily specify a custom favicon.
Currently the /favicon.ico view is hard-coded to do this: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/app.py#L179-L188
Some options:
- Allow
faviconpath to be set inmetadata.ymlsomehow, or via a--setting - Teach Datasette to check for
templates/favicon.icoand fall back to the defaultstatic/favicon.pngif that file does not exist - Document how to over-ride the favicon using the existing
--staticmechanism (if that's even possible) - Outsource this to a new plugin
Note that I need a way to set the content_type correctly too.
I think I want this to be a default feature, not a plugin.
Loading it using the existing templating system would be better I think, since that way both custom installations AND plugins could influence the favicon in the same way that they influence the templates.
The content type thing is a bit weird because usually I'd base that on the file extension, but here the favicon.ico file extension doesn't necessarily reflect if the image itself is a PNG or some other thing.
Annoyingly it looks like the standard library mimetypes module only uses filenames as the clue, it doesn't look at the bytes themselves.
I'm using that here: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/utils/asgi.py#L261-L277
https://pypi.org/project/python-magic/ can inspect files, but I don't want to add a whole new dependency just for this one feature.
I could use the imghdr standard library module, but frustratingly it's marked as deprecated in Python 3.11! https://docs.python.org/3/library/imghdr.html
I could vendor the necessary parts of imghdr - it's pretty tiny: https://github.com/python/cpython/blob/3.11/Lib/imghdr.py
https://www.w3.org/2005/10/howto-favicon suggests that it only needs to be able to identify PNG, GIF or ICO.
Based on https://github.com/python/cpython/blob/3.11/Lib/imghdr.py I'm tempted to say that if the file starts with b'\211PNG\r\n\032\n' then it's a PNG, if it starts with b'GIF8 then it's a GIF, anything else I assume an ICO.
Came up in office hours again today.
It might be helpful to have a little library of Datasette favicons. One for documentation, one for cloud, one for default Datasette, one for the Substack, and maybe some others colors to make it easier to keep track of which ports and datasettes are which.. Maybe even a set with the datasette logo, with superimposed labels 1, 2, and 3, in case we have three different ports running at a time. (Hmm... I see the Substack already does have a slightly different favicon color and maybe different size as well. Different enough to be able to distinguish the tabs. That's helpful.)
Maybe a little favicon designer hackathon, too! (The current default icon is VERRRY nerdy--maybe appropriate, but a slightly less nerdy favicon might be a draw?) The current icon also defaults (on my screen, anyhow) to a light color icon on a light color tab background. Doesn't stand out much. (Personally I couldn't create anything better, though). But now that Datasette can do so much ("multitool"), maybe the favicon should reflect that.