Imposia

API reference

Public React, Core, Client, and Viewer APIs for paginated HTML, publications, PDF viewing, navigation, diagnostics, print, and EPUB export.

Use this reference after you have rendered a first document. It covers the browser APIs application code calls directly, including every controller and React handle method. Core and Viewer require DOM APIs and do not run during server-side rendering.

Package map

PackagePurposePrimary APIs
@imposia/reactReact integrationImposiaPageViewer, ImposiaDocument, ImposiaPublicationViewer, both lifecycle hooks
@imposia/coreFramework-neutral pagination and publicationsmountPageDocument, mountPublication, prepareDocument
@imposia/viewerPresent committed pages or load a PDFmountPageViewer, mountViewer, deep-link helpers
@imposia/clientCombined framework-neutral entry pointRe-exports the primary Core and Viewer integration APIs

Import @imposia/react/styles.css once when you use the React package.

React components and hooks

ImposiaPageViewer and ImposiaDocument

ImposiaPageViewer mounts a Core page document, then binds the page Viewer after the first commit. ImposiaDocument is a compatibility wrapper with the same public props and handle types: ImposiaDocumentProps = ImposiaPageViewerProps and ImposiaDocumentHandle = ImposiaPageViewerHandle.

const viewer = useRef<ImposiaPageViewerHandle>(null);

<ImposiaPageViewer
  ref={viewer}
  source={{ html: "<main><h1>Report</h1></main>" }}
  documentOptions={{ page: { size: "A4", margin: "18mm" } }}
  viewerOptions={{ mode: "single", inspector: true }}
  onError={console.error}
/>;
PropTypeRequiredPurpose
sourcePageSourceYesHTML or light DOM to paginate.
sourceRevisionstring | numberNoForces an update when source identity/content comparison is otherwise unchanged.
documentOptionsPageDocumentOptionsNoCore pagination options.
documentOptionsRevisionstring | numberNoRemounts Core with new document options.
viewerOptionsPageViewerOptionsNoPage presentation, reader, and inspector options.
className, stylestring, CSSPropertiesNoHost div presentation.
onReady(document: PageDocument) => voidNoRuns after the document and Viewer binding are ready.
onError(error: unknown) => voidNoReceives Core or Viewer binding failures.
onStateChange(state: ImposiaDocumentState) => voidNoReceives idle, loading, ready, and error.

ImposiaPageViewerHandle

MemberReturnsConstraint
currentPageDocument | undefinedCurrent commit while mounted.
setMode(mode)voidAccepts continuous, single, or spread; throws before ready/after unmount.
setSpreadCover(cover)voidThrows before ready/after unmount.
openInspector(), closeInspector(), toggleInspector()voidRequire viewerOptions.inspector: true.
selectWarning(warning)voidRequires the inspector and a warning from its current generation.
print()Promise<void>Rejects before ready/after unmount.
exportEpub(options)Promise<Blob>Rejects before ready/after unmount.

ImposiaPublicationViewer

const publication = useRef<ImposiaPublicationViewerHandle>(null);

<ImposiaPublicationViewer
  ref={publication}
  snapshot={{
    metadata: { title: "Guide", language: "en" },
    entries: [{ id: "intro", title: "Introduction", html: "<h1>Introduction</h1>" }],
  }}
/>;

Its required snapshot prop accepts PublicationSnapshot. Optional props are snapshotRevision, publicationOptions, publicationOptionsRevision, viewerOptions (without reader), readerOptions (without controller), className, style, onReady, onError, and onStateChange. Revision props force updates/remounts as their names indicate. The component supplies the reader/controller binding.

ImposiaPublicationViewerHandle

All actions except current and resolveDestination throw after unmount. Reader actions also throw before the Publication reader is ready.

MemberReturnsEffect or constraint
currentPublicationDocument | undefinedCurrent commit while mounted.
resolveDestination(id)PublicationDestination | undefinedundefined before commit, after unmount, or for an unknown ID.
navigate(destination)voidA stale destination throws.
openTableOfContents(), closeTableOfContents(), toggleTableOfContents()voidControl the outline panel.
openThumbnails(), closeThumbnails(), toggleThumbnails()voidControl the thumbnail panel.
getThumbnails()readonly PublicationThumbnail[]Current-generation thumbnails.
selectThumbnail(thumbnail)voidA thumbnail from another generation throws.
restoreDeepLink(value)PublicationDestination | undefinedResolves and navigates a valid current link.
openSearch(), closeSearch(), toggleSearch()voidControl the search panel.
search(query)readonly PublicationSearchResult[]Searches the current commit.
nextSearchResult(), previousSearchResult()PublicationSearchResult | undefinedMove through results.
selectSearchResult(result)voidNavigates to a result.
setMode(mode), setSpreadCover(cover)voidControl page presentation.
openInspector(), closeInspector(), toggleInspector()voidRequire viewerOptions.inspector: true.
selectWarning(warning)voidRequires an inspector warning from the current generation.
print()Promise<void>Rejects before ready/after unmount.
exportEpub(options)Promise<Blob>Exports the latest commit; rejects before ready/after unmount.

useImposiaDocument and useImposiaPublication

useImposiaDocument(props: UseImposiaDocumentProps): UseImposiaDocumentResult;
useImposiaPublication(props: UseImposiaPublicationProps): UseImposiaPublicationResult;

Both hooks return a hostRef, lifecycle state, and a controller that is undefined until the mount effect creates it. Attach hostRef to one div. A loading or error state can retain the last committed document/publication.

useImposiaDocument accepts the page component's source, revision, options, and callbacks. HTML sources update when HTML/base URL changes; light-DOM sources update when node identity changes. sourceRevision forces an update, and documentOptionsRevision remounts the controller.

useImposiaPublication accepts the publication component's snapshot, revision, options, and callbacks. It updates when the snapshot reference or snapshotRevision changes; publicationOptionsRevision remounts the controller. Both hooks destroy their controller on cleanup and treat AbortError as lifecycle cancellation.

function Article({ html }: { html: string }) {
  const { hostRef, state } = useImposiaDocument({ source: { html } });
  return <div ref={hostRef} aria-busy={state.status === "loading"} />;
}

Core page document

mountPageDocument

mountPageDocument(
  container: HTMLElement,
  source: PageSource,
  options?: PageDocumentOptions,
): PageDocumentController;

The function appends one canonical iframe immediately, starts a staged generation, and returns synchronously. Await ready before reading the first document.

const controller = mountPageDocument(host, { html: "<article><h1>Hello</h1></article>" });
const pageDocument = await controller.ready;

PageSource is { html: string; baseUrl?: string } or { lightDom: Element | DocumentFragment; baseUrl?: string }.

PageDocumentOptions fieldType / purpose
cssreadonly string[]; additional authored CSS.
assetResolverAsync resolver for font, image, media, and stylesheet requests.
page{ size?, orientation?, margin? }; size accepts A4, Letter, or custom width/height.
limitsOptional input, node, asset, deadline, page, layout-pass, and generated-output limits.
headerTemplate, footerTemplateDecoration markup.
decorateBlankPagesWhether blank pages receive decorations.
experimental{ footnotes?: boolean; pageFloats?: boolean }.
extensionsOrdered PageExtension or PublicationExtension values.
signalCancels the initial generation.
onProgressReceives { completedPages } during commit.

An AssetResolver receives { url, kind, baseUrl, signal } and resolves to { status: "resolved", bytes, mimeType, resolvedUrl? } or { status: "blocked", reason? }.

PageDocumentController

MemberReturnsReadiness and errors
readyPromise<PageDocument>First commit, or rejection if it cannot commit.
currentPageDocument | undefinedPrevious commit remains during/after a failed update; cleared by destruction.
update(source, options?)Promise<PageDocument>Starts a generation; a newer update aborts the active one. Supports options.signal.
print()Promise<void>Waits for latest work, then prints the latest successful commit. Rejects with no commit/after destruction.
destroy()Promise<void>Aborts generation/export work, removes the iframe, releases resources, and waits for tracked work. Idempotent.

PageDocument

MemberType / returnMeaning
iframeHTMLIFrameElementCore-owned canonical frame.
generation, pageCountnumberCommit number and page count.
pagesreadonly PageMetadata[]Page number, side, name, blank state, geometry, dimensions, and body text.
warningsreadonly PageWarning[]Current-generation diagnostics.
timings{ totalMs; resourceMs; paginationMs }Generation timings in milliseconds.
exportEpub(options)Promise<Blob>Waits for latest active work and exports the latest committed semantic source.

EPUB options require metadata: { title, language, identifier, modified? } and optionally accept signal and { maxEntries?, maxBytes? } limits.

Core utilities

prepareDocument(html: string, options?: PrepareDocumentOptions): PreparedDocument;
pageWarningTargetBounds(document: PageDocument, warning: PageWarning): PageWarningTargetBounds | undefined;
hasPageDocumentFrameSandbox(iframe: HTMLIFrameElement): boolean;
selectBlankMarkers(markers: PageSideConstraint[], pages: Map<number, number>): number[];
  • prepareDocument synchronously normalizes/sanitizes HTML and returns { html, headerTemplate?, footerTemplate?, warnings }. Its options are headerTemplate, footerTemplate, and allowRemoteResources. API decoration options override embedded templates.
  • pageWarningTargetBounds returns live { left, top, width, height } in iframe viewport coordinates. It returns undefined for a foreign/unlocated warning.
  • hasPageDocumentFrameSandbox is true only for the exact public sandbox token set (allow-same-origin and allow-modals).
  • selectBlankMarkers returns marker IDs needing a blank to satisfy left/right parity, accounting for prior selections. It throws when a marker has no page mapping.

Core publication

mountPublication

mountPublication(
  container: HTMLElement,
  snapshot: PublicationSnapshot,
  options?: PublicationOptions,
): PublicationController;

It composes ordered entries into one page sequence and returns synchronously. Invalid snapshots or Publication extensions can throw during mounting.

const controller = mountPublication(host, {
  metadata: { title: "Handbook", language: "en" },
  entries: [
    { id: "cover", title: "Cover", html: "<h1>Handbook</h1>" },
    { id: "start", title: "Start", html: "<h1>Start</h1><p>First step.</p>" },
  ],
});
const publication = await controller.ready;

PublicationSnapshot contains metadata: { title, language?, identifier? } and ordered entries. Each entry requires id, title, optional baseUrl, and exactly one of html or lightDom. PublicationOptions contains PageDocumentOptions except that extensions accepts only PublicationExtension[].

PublicationController

MemberReturnsReadiness and errors
readyPromise<PublicationDocument>First committed Publication.
currentPublicationDocument | undefinedCurrent commit.
resolveDestination(id)PublicationDestination | undefinedResolves an outline/search ID in the current generation.
search(query)readonly PublicationSearchResult[]Empty before commit; otherwise searches the current index.
navigate(destination)voidThrows unless the complete destination matches and exists in the current generation.
update(snapshot, options?)Promise<PublicationDocument>Validates/stages a complete snapshot; supports options.signal.
print()Promise<void>Uses the page controller's latest-successful-commit behavior.
destroy()Promise<void>Destroys underlying page and Publication resources.

PublicationDocument extends PageDocument with committed metadata, entries, and nested outline. Each entry has an inclusive global pageRange. A PublicationDestination is { id, entryId, page, generation }; it is generation-bound. A search result is { entry, page, excerpt, destination }.

Viewer page documents, PDF, reader, and inspector

mountPageViewer

mountPageViewer(container: HTMLElement, document: PageDocument, options?: PageViewerOptions): PageViewerController;
validatePageViewerOptions(document: PageDocument, options?: PageViewerOptions): void;

Mount only after Core commits. container must be the canonical iframe's current parent. Validation checks the document, sandbox, theme, and optional reader synchronously.

PageViewerOptions accepts mode?: "continuous" | "single" | "spread", spread?: { cover? }, zoom?, theme?, inspector?, and reader?. A theme is a map of CSS properties whose names begin --imposia-viewer-.

PageViewerController

MemberReturnsEffect or constraint
goToPage(page), nextPage(), previousPage()voidClamp/advance within current pages or effective spreads.
setZoom(zoom)voidRounds/clamps finite input.
setMode(mode), setSpreadCover(cover)voidChange requested mode/cover layout.
setTheme(theme?)voidReplace or clear Viewer variables.
refresh(document)voidRequires the same iframe and a newer generation; throws after destruction/invalid input.
print()Promise<void>Rejects after destruction or when the iframe is unavailable.
destroy()voidRemoves Viewer bindings/UI and restores the Core iframe container. Idempotent.
statePageViewerStatePage, count, zoom, requested/effective mode, ready, and generation.
readerPublicationReaderController | undefinedPresent when reader options were supplied.
inspectorViewerInspectorController | undefinedPresent when inspector: true.

Narrow containers can report mode: "spread" with effectiveMode: "single".

Reader options require the PublicationController that owns the exact displayed PublicationDocument; they may include initialDeepLink and onDeepLinkChange.

PublicationReaderController memberReturns / effect
openTableOfContents(), closeTableOfContents(), toggleTableOfContents()Control the outline panel.
openThumbnails(), closeThumbnails(), toggleThumbnails()Control thumbnails.
selectThumbnail(thumbnail)Goes to a current-generation thumbnail; foreign thumbnails throw.
openSearch(), closeSearch(), toggleSearch()Control search.
search(query)readonly PublicationSearchResult[].
nextSearchResult(), previousSearchResult()PublicationSearchResult | undefined.
selectSearchResult(result)Selects/navigates to a result.
navigate(destination)Validates, navigates, and emits a deep link.
restoreDeepLink(value)PublicationDestination | undefined; resolves and navigates.
statePanel state, thumbnails, destination/deep link, query, results, and active result index.

All reader methods throw after destruction. Opening one auxiliary panel closes the others. PublicationThumbnail exposes page, generation, dimensions, and previewLineCount.

serializePublicationDeepLink(destination: PublicationDestination): string;
restorePublicationDeepLink(value: string, controller: PublicationController): PublicationDestination | undefined;

Serialization produces a versioned value from the destination ID. The standalone restore helper accepts only canonical encoding and resolves against the current generation; unlike the reader method, it does not navigate.

Viewer inspector

ViewerInspectorController memberReturns / effect
open(), close(), toggle()Control diagnostics; throw after destruction.
select(warning)Goes to/highlights a located warning; foreign-generation warnings throw.
state{ open, warnings, selected }.

mountViewer for PDF

mountViewer(container: HTMLElement, source: ViewerSource, options?: ViewerOptions): ViewerController;
type ViewerSource = Uint8Array | ArrayBuffer | string | { pdf: Uint8Array };

This separate Viewer loads/rasterizes PDF pages with PDF.js. Options are mode?: "continuous" | "single", zoom?, workerSrc?, and theme?. It returns immediately in loading; failures set state.status to error and populate state.error.

ViewerController memberReturns / effect
goToPage(page), nextPage(), previousPage()Navigate only while ready.
setZoom(zoom), setMode(mode)Update rendering only while ready.
setTheme(theme?)Replace/clear Viewer variables; ignored after destruction.
destroy()Cancels work, destroys PDF.js resources, and empties the container.
statePage, count, zoom, mode, loading/ready/error status, and optional error text.

Lifecycle and errors

SituationResult
First generation pendingcurrent is undefined; React state is loading.
Update pending after commitThe previous commit stays visible and in React state.
Newer update startsOlder active generation rejects with AbortError.
Caller abortsRelated generation/export rejects with DOM AbortError.
Update fails after commitPromise rejects; previous commit remains current.
Controller destroysWork aborts, resources/frame are released, and current clears.

ImposiaError extends Error with readonly code: string. Handle cancellation separately from reportable failures:

try {
  await controller.update(nextSource, { signal });
} catch (error) {
  if (error instanceof DOMException && error.name === "AbortError") return;
  if (error instanceof ImposiaError) console.error(error.code, error.message);
  throw error;
}

Viewer methods generally ignore calls that cannot operate in their current state. Ownership-sensitive calls throw: page Viewer mount/refresh validate the canonical iframe, Publication navigation rejects stale destinations, reader selection rejects foreign thumbnails, and inspector selection rejects foreign warnings.

On this page