Skip to content

Instantly share code, notes, and snippets.

@dardo82
Last active February 16, 2024 02:40
Show Gist options
  • Save dardo82/f7cc7c5c864fb5afa04bb12ecbcf3a9f to your computer and use it in GitHub Desktop.
Save dardo82/f7cc7c5c864fb5afa04bb12ecbcf3a9f to your computer and use it in GitHub Desktop.
Fix Safari FavIcons
#!/bin/zsh
# Fix Safari Favorites Icons
CS="cache_settings"; TIC="Touch Icons Cache"; DIR="$HOME/Library/Safari/$TIC/Images"
DB="$DIR/../${${TIC// }%%s*}${${(C)CS}//_}.db"; SQL=$(sqlite3 "$DB" "SELECT host FROM $CS")
sqlite3 "$DB" "UPDATE $CS SET ${${${(L)TIC// /_}#*_}//s/_is_in}=1, download_status_flags=1"
for png in "$1"/*.png; do URL="$(plutil -convert xml1 -o - "$DIR/../../Bookmarks.plist" | \
awk -F '[</>]' -v name="${${png##*/}%%.*}" '$3~name{getline;getline;getline;print $5}')"; \
cp -f -v "$png" "$DIR/${(U)$(md5 -q -s $URL)}.png"; done; chflags -v uappnd $DIR $DB*
@dardo82
Copy link
Author

dardo82 commented Dec 28, 2020

for eg. cp: /Google.png: No such file or directory

You have to pass an argument to the script, see here:
https://apple.stackexchange.com/questions/294606/how-to-get-icons-in-safari-favorites-aka-favicons-to-display-correctly/

@shearer123
Copy link

Hi, I have a problem, I was following the steps found on reddit:
https://www.reddit.com/r/mac/comments/kbfnbb/no_more_ugly_letters_heres_how_you_can_set/

But I cannot get it to work I ended up with the following message: "zsh: can't open input file: fixicon.sh"
I'm not sure where did I go wrong

@dardo82
Copy link
Author

dardo82 commented Mar 13, 2021

Hi, I have a problem, I was following the steps found on reddit:

Follow the instructions on StackOverFlow.

@iangray001
Copy link

iangray001 commented Apr 30, 2021

As I noted last year:

Final point, I also get attempt to write a readonly database but it seems that at least on Safari 13 you don't need to modify the database so it still works.

After closing and reopening Safari you'll see that it has still worked.

@shearer123
Copy link

@iangray001 Sorry, I deleted my question to phrase it better before I realized you've already replied.

Yes I did closed and reopened safari and re-run the script multiple times but it still didn't work. I'm not sure if it has to do with my recent update to macOS 11.3 (Safari 14.1) because my icons disappeared after the update. I used to be able to run it before no problem, but it's not working this time.

@iangray001
Copy link

iangray001 commented Apr 30, 2021

Strange. So I just tested it myself on 14.1 and it was working for me. Is it still correctly generating the hashes when run? Something along the lines of:

BBC News.png (www.bbc.co.uk) -> 251812C8741887CC7C6266920647E54E.png
Bring.png (web.getbring.com) -> 610AB171EE61AC87581065F4F76F22B5.png
Calendar.png (www.google.com) -> 0A137B375CC3881A70E186CE2172C8D1.png
Discord.png (discordapp.com) -> 8BC866E24CAECA1DC7AE2F77F094E5EC.png

EDIT: Oops, my version outputs that, not any of the versions on this gist! I've added it below:

#!/bin/sh
# Add Touch Icons to Safari's cache

# Theory of operation is that the domain from the URL of each bookmark is MD5 hashed and used as the filename of a PNG stored in $DIR
# The URL is the domain and subdomain, with no protocol, or path. So for example "app.slack.com" or "discordapp.com".
# Yes this means that multiple sites might collide, and seems to be a weakness of Safari's scheme.
# So this script searches Bookmarks.plist to find the bookmark in question, grabs the URL, hashes it, and copies the new icon named $DIR/${HASH}.png
# Usage: Create PNG files named the same as a bookmarks you want to add. So to add a Touch Icon for a bookmark called Gmail, create a PNG called Gmail.png. Run this script in the directory with the PNGs.

DIR="$HOME/Library/Safari/Touch Icons Cache/Images"

# If no argument is provided then assume the icons are in the current directory
ICONDIR=$1
if [ $# -eq 0 ]
then
	ICONDIR=`pwd`
fi

for png in "$ICONDIR"/*.png
do 
	BASENAME=`basename "${png%.png}"`

	#We use an XPath to find the URL because you can't reliably parse XML with regular expressions
	XPATH="//dict[dict/string='$BASENAME']/key[text()='URLString']/following-sibling::string[1]/text()"

	#Use plutil to convert the binary Bookmarks plist into raw XML, and xmllint to parse it
	URL=$(plutil -convert xml1 -o - "$DIR/../../Bookmarks.plist" | xmllint --xpath "$XPATH" -)

	#Strip out the protocol and everything after the first forward slash
	URL=`echo $URL | sed -e "s/http[s]*:\/\///g" -e "s/\/.*//g"`

	#md5 hash the URL and make it upper case
	HASH="$(md5 -q -s $URL | tr '[a-z]' '[A-Z]')"
	
	echo "`basename "$png"` ($URL) -> ${HASH}.png"
	cp -f "$png" "$DIR/${HASH}.png"
done

@dardo82
Copy link
Author

dardo82 commented Apr 30, 2021

Thanks for the updates, I'm on an old version of macOS.

@shearer123
Copy link

Thank you so much!

@zstzlmk
Copy link

zstzlmk commented May 2, 2021

@shearer123 11.3 broke my icons as well. I went to the /Users/%your_username%/Library/Safari/ folder, deleted the Touch Icons Cache folder completely and started over. This fixed it and the method still works very well. I'm the reddit guy, by the way c:

What's interesting is that before the deletion my icons were really sluggish to appear (turns out many files in the Touch Icons Cache slows the process down) and I had two website icons that would refuse to show up even with this method. But, after wiping out the folder and starting anew, the icons appear much faster and all of my websites now have an icon.

@sdwvit
Copy link

sdwvit commented Oct 4, 2021

deleting the db does not fix bookmarks icons

@dardo82
Copy link
Author

dardo82 commented Oct 4, 2021

deleting the db does not fix bookmarks icons

You mean it's a bug?

@sdwvit
Copy link

sdwvit commented Oct 4, 2021

@dardo82 I don't mean anything otherwise from the fact that this db state has no effect on bookmark favicons 🤷

@dardo82
Copy link
Author

dardo82 commented Oct 25, 2021

I’ve just checked and it still works!
Feels good when you can reuse it.

@ndesgranges
Copy link

Sometimes the icon will displa with a lower size, leaving borders. I could not understand why . See Netflix on the attached picture. Any one got any chance in solving this ?
image

@dardo82
Copy link
Author

dardo82 commented Jun 8, 2022

What's on the left?

@ndesgranges
Copy link

Another icon that fails to fill the expected space..
Capture d’écran 2022-06-09 à 20 29 16

@dardo82
Copy link
Author

dardo82 commented Jun 9, 2022

I suppose those are stock icons, use custom icons. 🧑‍💻

@ndesgranges
Copy link

Ok I did not explain It properly sorry. All the icons are custom ones. The stock ones (generated by Safari using favicon) are different so I can see it actually "works". I mean the script replaces the cache and it is displayed here (as seen on the screenshot). Though for some reasons, and only for some apps (not always the same btw), the icons do not fit the whole space, showing borders. I tried with different icons sizes, including huge ones. It happened after the last update, Safari was not part of the changelog though

@dardo82
Copy link
Author

dardo82 commented Jun 10, 2022

What was wrong with the stock icons then?

@ndesgranges
Copy link

For some websites: Not pretty
For some websites: Unknown (no favicon or something, the icon is just not found)
For some websites: Found but not fullscreen or other problems (which is kinda the same issue as "Not pretty")
I'm almost replacing all icons. Most work, some don't (or not as expected)

@dardo82
Copy link
Author

dardo82 commented Jun 12, 2022

So what about YouTube and NetFlix?

@ndesgranges
Copy link

As I'm replacing most icons so everything looks good, I'm replacing those too. I found images cropped those properly, and ran the script again. Those two fail to show properly which is not the case of every icons. But sometimes I rerun the script and they do show properly, only, other icons don't.. For example today, YouTube fills the whole icon, yeay (but Netflix don't ..)

Capture d’écran 2022-06-13 à 20 13 40

@dardo82
Copy link
Author

dardo82 commented Jun 13, 2022

So it's seemingly random behaviour?

@clementduncan
Copy link

clementduncan commented Jan 31, 2023

Sometimes the icon will displa with a lower size, leaving borders. I could not understand why . See Netflix on the attached picture. Any one got any chance in solving this ?
image

Within ~/Library/Safari/Touch Icons Cache/TouchIconCacheSettings.db the column transparency_analysis_result seems to change how the image is displayed.
I've found changing it to 1 can remove the border spacing.
It initially seems to cause an issue where adding/renaming/removing bookmarks in Safari, however this seems to fix itself after a few minutes. It's possibly to do with the hashing changing on file verification.

@dardo82
Copy link
Author

dardo82 commented Jan 31, 2023

Thanks for the interesting tidbits.

@0x1D-1983
Copy link

Funky thread! I landed here while investigating why the SVG favicon I added to a website I'm working on doesn't show on mobile Safari but it shows correctly on Safari Desktop. I still couldn't figure it out but while reading through these posts I gladly concluded I am not the only person completely crazy about how my icons look on the screen. And I'm not just talking about favicons. I have my own app dock icons as well. If a software update changes the icons to a white rectangled version (the current trend) I replace it with my own (a freeform icon) and clear the cache. :)

@dardo82
Copy link
Author

dardo82 commented Nov 3, 2023

What site is it?

@0x1D-1983
Copy link

@dardo82
Copy link
Author

dardo82 commented Nov 3, 2023

It works on Android.

@0x1D-1983
Copy link

That's good to know, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment