Lessons Learned from Implementing an Inline Document Viewer

My software development team recently worked on a feature allowing users to preview documents (primarily PDF, HTML, and images) in a reader modal, instead of having to disrupt their workflow by being redirected out to a new tab or requiring unnecessary file downloads. Here, I’ll describe some of the lessons learned from implementing an inline document viewer. This includes the importance of where the file is being served from and how the response/metadata included on the requested file influences how the document can be interacted with.

Pre-Querying Document Metadata

It’s important to know information about the type of file being previewed up front. Most importantly is the MIME type of the file, because it influences how the file will be rendered; PDF and HTML with an <iframe>, images with <img>, and other unexpected file types falling back to a download prompt. If all you have is a document identifier or URL, you should consider pre-querying document metadata.

If there is an endpoint already available to get document metadata like the MIME type, file name, or access details (or if you can add an endpoint like this), use that. Otherwise, fetch the document itself and inspect the response headers.

Content-Type

The Content-Type header describes the media type of the returned file contents, so we can inspect this to determine whether we’re dealing with PDF, HTML, image, or something else. But even if you know/trust that a file is a certain type, it’s important that the Content-Type actually matches this expectation.

For example, some of the PDFs that we were retrieving from a third party had a Content-Type response header of binary/octet-stream. While this content type can be downloaded into a PDF just fine, it cannot be rendered in the browser, and will always be automatically downloaded. This is true even if using something like an <embed> or <object> that allows you to explicitly state the expected media type.

Content-Disposition

The Content-Disposition consists of two parts: the display behavior and an optional filename — for example Content-Disposition: inline; filename=example.pdf.

If inline is set on the header, the document can be rendered in an iframe or opened in another browser tab without requiring a download. If attachment is set, it will always force a download.

filename drives the suggested file name for download links, or when the save as dialog is launched. The download attribute on an <a> will be ignored, in favor of this value. If omitted, the suggested file name be the path of the requested document, or a default value like ‘document’ or ‘download’, depending on the browser.

Proxying Document

Ideally, you have control over the response headers of the requested documents, and can send the values needed for the frontend behavior desired.

But, if you can’t do so, you may need to consider proxying the request for the document through your own web server since these two response headers determine quite a lot about how the document can be interacted with.

So, the request goes from your web client to your web server to the remove server and the back again, where your server can change the filename or specify that viewing the document inline is preferred.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *