The Logical Table of Contents in EPUB: nav.xhtml and What It Actually Does

A hidden navigation ribbon and a visible contents plane connect to the same chapters

To diagnose an EPUB's logical table of contents, first check whether nav.xhtml is registered as the Navigation Document and whether its table-of-contents links point to body targets that actually exist. If nav.xhtml is also in the reading order, the same file can appear as an in-book contents page. If it is not, app navigation may still work without a visible page.

This article is about registration, links, and reading order as separate failure points. Choosing where an in-book contents page belongs is covered elsewhere.

nav.xhtml supplies the relationships used for navigation

The EPUB 3 Navigation Document is an XHTML document containing navigation elements, including a table of contents. The package document identifies which resource is the Navigation Document. Reading systems use that relationship to expose chapter navigation. The formal requirements are in W3C EPUB 3.3.

The important distinction is that being the logical navigation and being a visible page are separate conditions.

One nav.xhtml can satisfy all three, but EPUB 3 does not mean every book must show the Navigation Document as an in-book page.

Let the symptom choose the check

Work through the failure points in this order:

  1. Nothing appears in the app's contents control — check Navigation Document registration and the table-of-contents navigation
  2. Labels appear but do not move to chapters — check that every link target exists inside the EPUB
  3. App navigation works but no in-book contents page appears — check whether nav.xhtml is in the reading order
  4. Modern apps work but an older target does not — if legacy support is part of the release plan, inspect toc.ncx separately and compare its entries

Number three is not necessarily a fault if the publisher intentionally omitted an in-book contents page. Conversely, merely finding a file named nav.xhtml is not enough. Its registration, link targets, and reading-order status are different facts.

A hand-built EPUB needs three separate checks

When assembling by hand, create nav.xhtml, register it in the package document, write the table-of-contents links, and add it to the reading order only if it should appear as a page. If legacy support is a release requirement, maintain toc.ncx separately.

Adding a chapter is therefore more than adding a file name. Check the navigation target, the body reading order, and the legacy entry when applicable. Mixing those layers produces partial failures such as “the page is visible but the app has no contents” or “the label appears but the link goes nowhere.”

A compact checklist is enough:

Compare toc.ncx only when the release plan includes that legacy navigation path.

What was verified in rune Studio output

I drove the development build from the command line, exported an EPUB from two chapters, and inspected it. The output showed:

This establishes that the tested Rune Studio output used one contents document for logical navigation and an in-book page, while also generating toc.ncx. It does not mean every EPUB production workflow must have that structure.

Excluding an entry leaves the body page in place

Exporting with chapter three excluded removed its navigation entry while leaving the chapter page in the reading order. Inclusion in the book and exposure as a navigation destination are separate editorial decisions.

Keep the inspection result within scope

Rune Studio's inspection reports navigation presence, legacy navigation presence, and the reading order. The operation test did not establish which form every reading app uses or how each device presents it.

Who this article is for

Use this diagnostic when the app's contents control is empty, a label does not jump, or only the in-book page is missing. If your only decision is where the visible contents page belongs, the reading-order article is the more direct guide.

If your production tool generates navigation, you may never need to edit nav.xhtml by hand. You should still test three things before submission: app navigation exists, each entry moves to the intended chapter, and the in-book page appears only if you chose to include one.

Summary

As a first step, ignore the page appearance and test whether the app's contents control moves to each chapter. If it fails, inspect registration and targets; if it works but the page is absent, inspect the reading order.

See the current product scope on the Rune Studio product page.