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.

comic-book.js exports a single function, makeComicBook, that turns a CBZ (Comic Book Zip) archive into a book object compatible with the foliate-js fixed-layout renderer. Each image file inside the archive becomes one section (page), sorted in natural numeric order. The module is synchronous — it does not perform any I/O itself, deferring all file access to the loader object provided by the caller.

makeComicBook(loader, file)

const { makeComicBook } = await import('./comic-book.js')
book = makeComicBook(loader, file)
Synchronous function. Returns a book object immediately. Image loading is deferred until a section’s .load() method is called.
loader.entries
array
required
Array of entry objects, each with a filename string property containing the full path of the file within the archive. This is the only book parser in foliate-js that reads loader.entries directly to enumerate the archive contents.
loader.loadBlob
function
required
Async function. Given a path string, returns the file as a Blob. Used to load each image when its section is rendered.
loader.getSize
function
required
Function. Given a path string, returns the file size in bytes. Used to populate the .size property on each section for reading-progress calculations.
file
File | Blob
required
The original archive file object. Its .name property is used as the book title in the returned metadata.

Supported image formats

The function filters archive entries to those with the following extensions: .jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .jxl, .avif Files that do not match these extensions are ignored. The remaining files are sorted using Intl.Collator with numeric: true, so that filenames like page-2.jpg and page-10.jpg sort in the expected reading order. If no supported image files are found, the function throws an error.

Zip loader

makeComicBook uses the same loader interface as epub.js. In view.js, the loader is created with makeZipLoader:
const makeZipLoader = async file => {
    const { configure, ZipReader, BlobReader, TextWriter, BlobWriter } =
        await import('./vendor/zip.js')
    configure({ useWebWorkers: false })
    const reader = new ZipReader(new BlobReader(file))
    const entries = await reader.getEntries()
    const map = new Map(entries.map(entry => [entry.filename, entry]))
    const load = f => (name, ...args) =>
        map.has(name) ? f(map.get(name), ...args) : null
    const loadText = load(entry => entry.getData(new TextWriter()))
    const loadBlob = load((entry, type) => entry.getData(new BlobWriter(type)))
    const getSize = name => map.get(name)?.uncompressedSize ?? 0
    return { entries, loadText, loadBlob, getSize }
}
view.js selects the CBZ path when the file’s MIME type is application/vnd.comicbook+zip or its name ends with .cbz.

Returned book object

Property / methodDescription
.sectionsOne section per image file. Each has .load() (returns a blob URL for an HTML page wrapping the image), .unload() (revokes the blob URLs), and .size.
.tocOne TOC entry per image, with .label set to the filename and .href set to the filename (used as a section ID).
.metadataObject with .title set to file.name.
.rendition{ layout: 'pre-paginated' } — signals to view.js that the fixed-layout renderer should be used.
.resolveHref(href)Returns { index } for the section whose .id matches the href.
.splitTOCHref(href)Returns [href, null].
.getTOCFragment(doc)Returns doc.documentElement.
.getCover()Returns a Blob for the first image in the archive.
.destroy()Revokes all blob URLs created for loaded sections.
Each section’s .load() creates two blob URLs: one for the raw image and one for a minimal HTML wrapper page (<img> inside a <body style="margin: 0">). Both are revoked together when .unload() is called.

Build docs developers (and LLMs) love