Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/johnfactotum/foliate-js/llms.txt

Use this file to discover all available pages before exploring further.

fixed-layout.js registers the <foliate-fxl> custom element, the fixed-layout renderer for pre-paginated content. It loads each section into a sandboxed iframe, reads the viewport dimensions declared in the document (via <meta name="viewport">, the SVG viewBox, or the book’s rendition viewport), scales the page to fill the container, and handles two-page spreads according to the EPUB page-spread properties. It is used automatically by <foliate-view> whenever book.rendition.layout === 'pre-paginated', and also for CBZ archives and PDF files.

Import

import './foliate-js/fixed-layout.js'

const fxl = document.createElement('foliate-fxl')
document.body.append(fxl)

Core methods

open(book)

Opens a book object. Reads book.rendition.spread and book.rendition.viewport to configure spread layout, then builds an internal spread map from book.sections using each section’s pageSpread property ('left', 'right', or 'center').
book
object
required
A book object that satisfies the foliate-js book interface. The renderer reads the following additional properties:
  • book.dir — page progression direction ('rtl' or 'ltr').
  • book.rendition.spread — spread mode. When 'none', every section is displayed as a centred single page regardless of its pageSpread property.
  • book.rendition.viewport — fallback viewport string or { width, height } object used when a section document does not declare its own viewport.
const book = await makeBook(file)
fxl.open(book)

goTo(target)

Navigates to a resolved destination. Looks up the spread that contains book.sections[resolved.index] and displays that spread.
target
object | Promise<object>
required
An object (or a Promise that resolves to an object) with:
  • index (number, required) — the section index to navigate to.
  • anchor — ignored by the fixed-layout renderer (positions within a page are not supported).
await fxl.goTo({ index: 4 })

prev() / next()

Navigate backward or forward by one spread. In portrait mode (when the container height exceeds its width and the spread mode is not 'both' or 'portrait'), a two-page spread is shown one page at a time, so calling prev()/next() may move within the same spread before advancing to the next one.

getContents()

Returns an array of objects, one per iframe currently rendered (up to two for a two-page spread). Returns Array<{ doc: Document }>.
The fixed-layout renderer does not currently populate index or overlayer in the returned objects. Annotation support for fixed-layout content is not yet implemented.
const frames = fxl.getContents()
for (const { doc } of frames) {
    console.log(doc.title)
}

goToSpread(index, side, reason?)

Low-level method that navigates directly to a spread by its index in the internal spread array. Prefer goTo() for normal navigation.
index
number
required
The spread index (not the section index).
side
string
required
Which page of a two-page spread to treat as the “active” page for location reporting: 'left', 'right', or 'center'.
reason
string
Passed through to the relocate event’s detail.reason field.

getSpreadOf(section)

Returns the spread index and side for a given section object.
section
object
required
A section object from book.sections.
Returns { index: number, side: 'left' | 'right' | 'center' }, or undefined if the section is not found.

destroy()

Disconnects the internal ResizeObserver. Call this when removing the element from the DOM.

Attributes and properties

zoom (attribute)

Controls the scale applied to page iframes. Set with setAttribute('zoom', value).
zoom
string
Accepted values:
  • A numeric string (e.g. "1.5") — scales the page by that factor.
  • "fit-page" (default behaviour when unset) — scales so the spread fits entirely within the container in both dimensions.
  • "fit-width" — scales so the spread fills the full container width, possibly cropping vertically.
fxl.setAttribute('zoom', '1.5')       // 150% zoom
fxl.setAttribute('zoom', 'fit-width') // fill width
fxl.setAttribute('zoom', 'fit-page')  // fit entirely (default)
fxl.removeAttribute('zoom')           // same as fit-page
The zoom attribute is the only observed attribute: static observedAttributes = ['zoom'].

spread (property)

Set automatically by open() from book.rendition.spread. Controls whether two-page spreads are shown.
ValueEffect
'none'All sections rendered as centred single pages.
'both'Two-page spreads always shown, even in portrait orientation.
'portrait'Two-page spreads shown in portrait orientation as well.
Any other value / unsetTwo-page spreads shown only when the container is wider than it is tall.

defaultViewport (property)

Set automatically by open() from book.rendition.viewport. Used as the fallback viewport when a section document does not declare its own viewport dimensions. You can assign this before calling open() to override the book’s declared viewport.

index (getter)

Returns the section index of the currently visible page, derived from the active spread and the current side.
console.log(fxl.index) // e.g. 4

rtl (property)

Set automatically by open() to true when book.dir === 'rtl'. Reverses the meaning of prev() and next() so that navigation follows the page progression direction.

Viewport detection

When loading a section, the renderer determines the page dimensions in this order:
  1. SVG viewBox attribute (for sections whose root element is <svg>).
  2. <meta name="viewport" content="width=..., height=..."> in the section’s <head>.
  3. fxl.defaultViewport (set from book.rendition.viewport).
  4. Natural dimensions of the first <img> element in the document.
  5. Fallback of 1000 × 2000 with a console warning.

CSS filter part

Like <foliate-paginator>, the fixed-layout renderer exposes a filter part on each page iframe. When used through <foliate-view>, the view element re-exports this part automatically via exportparts.
foliate-view::part(filter) {
    filter: invert(1) hue-rotate(180deg);
}
The filter applies only to the book content inside the iframes, leaving any overlaid elements unaffected.

Events

All events are CustomEvents dispatched on the <foliate-fxl> element.

load

Fired after a section document finishes loading into its iframe.
doc
Document
The loaded section’s Document object.
index
number
The section index of the loaded document.

relocate

Fired after a spread is displayed or when the visible page within a spread changes in portrait mode.
reason
string
Why the relocation happened. 'page' for user-initiated navigation, or the value passed to goToSpread().
range
null
Always null for fixed-layout content — there is no visible text range to report.
index
number
The section index of the currently active page.
fraction
number
Always 0 for fixed-layout content.
size
number
Always 1 for fixed-layout content (each page is its own section).

create-overlayer

Fired when the renderer is ready to accept an overlay for a section. The handler must call event.detail.attach(overlayer) with an Overlayer instance.
Overlay support in the fixed-layout renderer is a work in progress. The index property in the event detail and the overlayer property in getContents() results are not yet populated.
doc
Document
The section document.
index
number
The section index (currently unpopulated — see note above).
attach
function
Call with an Overlayer instance to attach it to the page.

Build docs developers (and LLMs) love