Skip to content
Apertura
Frameworks

React

A component for the common case, and a hook for everything the component does not cover.

The component

DocumentViewer renders the container, opens the file and layers the loading, error and empty states over it. The container is never unmounted between states: recreating it would lose the scroll position and force the view to be rebuilt.

Pane.tsx
import { DocumentViewer } from '@apertura/react';

<DocumentViewer
  file={file}
  fit="width"
  zoom={1}
  initialPage={0}
  renderLoading={(progress) => <Spinner value={progress} />}
  renderError={(error) => <Failed message={error.message} />}
  renderEmpty={() => <DropHint />}
  onStateChange={(state) => setStatus(state.status)}
/>;

Props

PropTypeNotes
fileFile | Blob | ArrayBuffer | Uint8Array | stringA string is treated as a URL. Passing undefined closes the document.
fit'width' | 'page' | 'none'How a page is fitted into the container.
zoomnumber1 means 100%. Changing it re-runs layout only, not parsing.
registryFormatRegistryRestricts which formats are bundled and accepted.
tolerantbooleanDefaults to true: real files break the specification routinely.
passwordstringFor encrypted documents, once decryption lands.

The hook

useAperturabinds a viewer to a component's lifecycle and hands back the container ref, the state and the imperative calls. State is read through useSyncExternalStore: the viewer is the external source of truth, which avoids duplicating it in useState and avoids tearing under concurrent rendering.

Reader.tsx
import { useApertura } from '@apertura/react';

export function Reader({ url }: { url: string }) {
  const { containerRef, state, open, close, viewer } = useApertura({ fit: 'width' });

  useEffect(() => {
    void open(url);
    return close;
  }, [url, open, close]);

  return (
    <>
      <button onClick={() => viewer?.view?.goToPage(4)}>Page 5</button>
      <div ref={containerRef} style={{ height: '80vh' }} />
      {state.status === 'loading' && <progress value={state.progress} />}
    </>
  );
}
Reaching the format-specific API
viewer.view is the live view — DocxView, XlsxView or PptxView. Page navigation, bookmarks, outline and zoom live there, because what they mean differs per format.

State

state.status is one of idle, loading, ready and error. Alongside it are progress (0 to 1), detection (what the bytes turned out to be) and document (the parsed model, for metadata and outline).