I recently had an issue where fonts loaded via link HTML element with crossorigin="anonymous"
attribute would mysteriously not load but only in safari (both ios and macOS). Firefox and Chrome on Linux desktop and android mobile were handling the same code without an issue.
For the purpose of this post – the domain in question: https:www.example.com
Example font preloading code:
<link rel="preload" as="font"
href="https://example.com/my-awesome-font.woff2"
type="font/woff2" crossorigin="anonymous">
The error I was seeing in the console in Safari browser (had to use BrowserStack just to debug this):
origin "https://www.example.com" is not allowed by Access-Control-Allow-Origin
^ You might be already seeing the issue, but please remember – the same code works in all other browsers but safari without any issues.
Investigating the issue
There is this entire thread going on StackOverflow discussing what seems to be the same issue – that I went over but could not find anything actionable.
My site setup involved storing fonts in AWS S3 fronted by CloudFront – so the obvious path led to investigating my AWS setup. I found some little inconsistencies with AWS setup – issues like GET, HEAD, OPTIONS enabled on CloudFront but only GET, HEAD in S3 bucket with fonts – but that wasn’t the issue (in fact I don’t think I ever fixed it).
But I have confirmed that S3 is configured to respond back with the proper CORS header (yes I know – the proper way is to whitelist specific domains, alas here we are), ex:
access-control-allow-origin: *
I have also confirmed that CloudFront is configured to properly forward all the headers that I thought could be needed:
Weird, right?
What solved it
Now if you look carefully at that error message you may have already spotted the issue. Where I thought I load fonts from the same domain – well not quite. I know we are all so used to the bare domain being interchangeable with the www domain – but they are not quite the same.
After I corrected the code to load the fonts from the www domain – the issue magically got resolved:
<link rel="preload" as="font"
href="https://www.example.com/my-awesome-font.woff2"
type="font/woff2" crossorigin="anonymous">
Additional thoughts
Now while the issue got resolved for me by simply making sure the domain is exactly the same – there is definitely what seems to be some bug – perhaps not even in Safari WebKit (although it is the only browser with a problem) but in AWS S3.
The above code fix would not have corrected the issue for me would I had truly needed to load the fonts cross-domain.
The root of the issue appears to be perhaps broken CORS implementation in S3 where it is not returning the Vary: Origin
header, see this chrome bugreport and stackoverflow thread but in full disclosure – I have not had time to explore that in depth.
Thanks for reading.