microscope-js - v0.0.0
    Preparing search index...

    Module @microscope-js/react

    @microscope-js/react

    npm Bundle Types Provenance

    React + Next.js adapter for microscope-js. One <Viewer /> component, one useViewer() hook for fully custom UIs, one useRegistry() helper. SSR-safe — works inside the Next.js App Router with 'use client'.

    pnpm add @microscope-js/react @microscope-js/core
    # plus whichever format renderers you actually need
    pnpm add @microscope-js/renderer-pdf @microscope-js/renderer-image

    Peer deps: react >= 18, react-dom >= 18.

    'use client';
    import { Viewer, useRegistry } from '@microscope-js/react';
    import { pdfRenderer } from '@microscope-js/renderer-pdf';
    import { imageRenderer } from '@microscope-js/renderer-image';

    export default function FilePreview({ file }: { file: File }) {
    const registry = useRegistry([pdfRenderer, imageRenderer]);
    return (
    <Viewer
    source={file}
    registry={registry}
    style={{ height: 600 }}
    loadingFallback={<Spinner />}
    errorFallback={(err) => <Alert>{err.message}</Alert>}
    emptyFallback={<DropHint />}
    />
    );
    }

    source accepts a File, Blob, ArrayBuffer, Uint8Array, URL, or string URL.

    When you want full control over the toolbar / chrome around the viewer:

    'use client';
    import { useViewer, useRegistry } from '@microscope-js/react';
    import { pdfRenderer } from '@microscope-js/renderer-pdf';

    export function MyPdfViewer({ file }: { file: File }) {
    const registry = useRegistry([pdfRenderer]);
    const { containerRef, loading, error, handle } = useViewer({ source: file, registry });

    const pageCount = handle?.capabilities?.pageCount as number | undefined;

    return (
    <div className="my-frame">
    {loading && <Spinner />}
    {error && <Alert>{error.message}</Alert>}
    {pageCount && <span>{pageCount} pages</span>}
    <div ref={containerRef} className="my-canvas" />
    </div>
    );
    }
    Prop Type Description
    source Source | null | undefined What to render. null shows the emptyFallback.
    registry Registry From useRegistry([...]) or createRegistry([...]).
    rendererId? string Force-pick a renderer by id (skips matching).
    options? Record<string, unknown> Forwarded to the matched renderer.
    className? string Container class.
    style? CSSProperties Container inline style. Default is a 16:9 box with a subtle border.
    loadingFallback? ReactNode Shown while a render is in flight.
    errorFallback? (err) => ReactNode Render prop for errors.
    emptyFallback? ReactNode Shown when source is nullish.

    The adapter is SSR-safe — on the server it returns the wrapper div and nothing else. The format-specific renderer is only loaded inside useEffect. You can use it in two ways:

    • Mark the parent file with 'use client' (recommended — keeps it simple)
    • Or import dynamic from 'next/dynamic' and load with { ssr: false }

    pdfjs-dist, mammoth, xlsx, and jszip are loaded via import() so they never end up in the SSR bundle.

    useViewer cancels the previous in-flight render and tears down the previous handle whenever source, registry, rendererId, or options change. Swapping files is safe and leak-free; object URLs are revoked on teardown.

    MIT

    Interfaces

    UseViewerOptions
    UseViewerResult
    ViewerProps

    Functions

    useRegistry
    useViewer
    Viewer