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
favicon
path to be set inmetadata.yml
somehow, or via a--setting
- Teach Datasette to check for
templates/favicon.ico
and fall back to the defaultstatic/favicon.png
if that file does not exist - Document how to over-ride the favicon using the existing
--static
mechanism (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.