Normally when I have a strange error, it is either a mistake on my part or a well documented bug with a workaround. However when I searched the web today for a problem we noticed in Safari, there was nothing imediately jumping out as a relevant answer.
To help others searching for information to hopefully find the fix on this page, these are the kind of things I was searching for: "Safari can't load PDF", "Grey box when previewing PDF in Safari", "Large files break Safari PDF", "Safari byte range error".
And to answer the question, the fix is to use iframe
instead of embed
.
Note that PDF preview on iOS Safari has its own problems, so this solution may potentially make it worse on iOS.
In the interest of journalling my development work being something I rarely do but never regret, here's a brief story.
This was a head scratcher. Why would previews of PDF files intermittently fail to load? It felt like a race condition of some kind. Thankfully given this issue was noticed in Safari, we focussed on that browser as it turned out to be a Safari-specific issue. It wasn't all files, in fact from the few that we were comparing it appeared to only be the 2MB file that failed and not the smaller files. Now, 2MB isn't massive so that seemed like it could well have been a red herring... surely Safari could handle a 2MB file.
So naturally, we looked into the network requests to check if the data was coming back correctly. The way it was set up was that the backend would give a signed url for the frontend to request the file, this work was recently modified a bit so there was the possibility that it was a regression caused by a recent change. This is how it usually happens isn't it, a bunch of different possibilities that are all fairly reasonable and would all probably have simple solutions but can often cause us to go down the rabbit hole to find which solution is needed.
Looking at the network request, it became clear that when the error happened it was due to no response from the server. It would say "An error occurred trying to load the resource". Now, normally when this happens, I've learned to click "Response" in the right hand corner of the Safari Dev Tools and change it to "Response (Object tree)". That usually then shows the relevant information, I've no idea why the default view isn't more useful. However on this particular time, this select box wasn't showing up so I had to look elsewhere to figure out the error.
The failed request had the words "Byte range". I wasn't able to get any more useful information than that... so I went to my search engine and didn't much further either. We were bouncing ideas back and forward, one was to set up a test harness that would generate files to see at which size it failed. But even if that were to give us a clear answer, it wouldn't have solved the problem. It was an intermittent bug, that appeared to only affect Safari. So it seemed like it must be a browser issue, but surely we wouldn't have been the first ones to notice it?
Most of the search results related to videos and audio files not working, but none seemed to match our issue. That was until eventually, thankfully, we found an issue "Safari on Big Sur freezes when embedding PDF file" on the PDFObject repo on GitHub. This didn't directly mention the failed request (though it does mention a duplicated request byte range which we noticed too) but it does mention a grey box, so it was worth a go.
Lo and behold, it did work... we just needed to use an iframe
instead of an embed
. Development is "fun"!