If you’ve seen this message from epubcheck, you know where this post is going.
It’s easy to get tripped up on EPUB’s web-like, but not quite web, quirks, as what is valid to do on in a web page isn’t always valid to do in an EPUB. Particularly when it comes to linking to resources, as you have to follow EPUB’s core media type requirements.
If epubcheck has spewed the “hyperlink to non-standard resource” message at you, it’s because you can only have internal links go to XHTML or SVG documents, at least without a fallback.
But don’t fret. There are some easy, and not-so-easy, workarounds to this problem, which is what I’m going to look at.
Links and the spine
For the sake of this post, let’s pretend we’re trying to link to a PDF and this is the problematic markup:
<a href="forms/tax-form.pdf">2014 T1 Form</a>
Everything looks good from an HTML perspective, right? You’ve put your PDF file in the forms subdirectory, and you want the user to be able to open the document if their reading system supports PDF. A browser would have no problem with this, so why the error from epubcheck?
The problem is one of internal versus external linking. Internal (or relative) links — ones that don’t start with a protocol like http: or https: — are expected to reference only EPUB content documents in the spine by default (the XHTML or SVG restriction I mentioned). Since PDF is not XHTML or SVG, you get the linking error.
Epubcheck is effectively telling you that what you’re trying to do is likely to choke a reading system, since it’s not required to render PDFs in the content flow.
If the link were to an external PDF, there would be no problem at all:
<a href="http;//gov.example.com/forms/tax-form.pdf">2014 T1 Form</a>
As now it’s no longer incumbent upon the reading system to open this link as part of the ebook. It can launch an external app, like a browser, and let it handle the download and launching of the resource. EPUB’s spine restrictions no longer apply, in other words.
Maybe linking out to the web is all you’re looking for to solve your problem, but more often it’s an insufficient workaround. So what do you do if you have to include the resource… manifest fallbacks!
The only way to link to a non-EPUB content document is to provide an EPUB content document as a fallback.
For example, if this is the entry for the PDF in the package document manifest:
<item id="t1" href="forms/tax-form.pdf" media-type="application/pdf"/>
You’ll have to add a
fallback attribute that points to the entry of either an XHTML or SVG fallback:
<item id="t1" href="forms/tax-form.pdf" media-type="application/pdf" fallback="t1-xhtml"/>
<item id="t1-xhtml" href="forms/tax-form.xhtml" media-type="application/xhtml+xml"/>
Here’s where things start to get a little murky, however.
While it makes the most sense that the fallback contain the equivalent content, it’s not always possible. For accessibility reasons, you should try to give an equivalent, but say it’s legally dubious to reproduce a government tax form.
While EPUB requires a fallback that can be rendered, the specification does not mandate what has to be contained in that fallback. If you can’t reproduce the content in a meaningful way, or at all, at the very least you should provide a message in the fallback indicating what the file contained and why it’s not loading (i.e., that it’s in a format the reading system is not designed to handle).
If the resource also lives out on the web, but you included it for convenience, adding a link in this fallback document is another way to give the reader access to the source.
A little creativity can go a long way.
You might be saying to yourself at this point that that’s all and good for obvious non-core media types like PDF, but I’m just trying to link from a thumbnail jpeg to its full-size version. Or I want an MP3 to open and play automatically when the reader clicks the link.
It doesn’t matter that those are core media types for use within content documents. As soon as you try to link to them directly, you’re treating them like they are content documents.
And once again, since only XHTML and SVG content documents are allowed in the spine without fallbacks, you either have to wrap the resource up as XHTML or SVG or provide a fallback. Since the fallback is going to be an XHTML or SVG document containing the resource, there’s almost no point in bothering to reference core media types directly.
This linking problem is most likely to bite you when you build an EPUB with the mindset that it’s just plain old web pages, or when you compile up web content that wasn’t developed with EPUB’s restrictions in mind.
It might seem like a nuisance to have this restriction, but you have to remember that a reading system is not exactly a browser, and it’s rendering your content in the reading pane. While it might handle non-core media types natively, expecting resources of your ebook to render in the content pane or be launched into another application is not what reading systems are about.
There are also greater security considerations if a reading system were expected to launch whatever random files were included in the container.
But that’s enough on linking for today.