PDFSlick: visor y render de PDF en React con estado via Zustand

Contexto

Necesitaba mostrar un PDF dentro de una app React con thumbnails, zoom y busqueda, sin armar todo el visor a mano sobre pdf.js.

Lo que aprendi

PDFSlick envuelve pdf.js y expone el estado del documento (pagina actual, zoom, thumbnails) como un store de Zustand. Eso permite construir UI custom (toolbar, panel de miniaturas) leyendo el mismo store, en vez de pelear con el API imperativo de pdf.js.

El gotcha que me costo runtime (no lo agarra el build): en Vite hay que configurar el worker de pdf.js a mano. Sin esto, pdf.js cae a un "fake worker", el documento nunca carga y la UI muestra Pagina 0 / 0:

import { GlobalWorkerOptions } from "pdfjs-dist";
import pdfWorkerUrl from "pdfjs-dist/build/pdf.worker.min.mjs?url";

GlobalWorkerOptions.workerSrc = pdfWorkerUrl;

Detalle clave: pdfjs-dist debe estar en la MISMA version que usa @pdfslick/core (en mi caso 6.0.227); si no, el worker es incompatible.

Ejemplo

import { usePDFSlick } from "@pdfslick/react";
import "@pdfslick/react/dist/pdf_viewer.css";

function Viewer({ url }: { url: string }) {
  const { viewerRef, usePDFSlickStore, PDFSlickViewer } = usePDFSlick(url);
  const pageNumber = usePDFSlickStore((s) => s.pageNumber);
  const numPages = usePDFSlickStore((s) => s.numPages);

  return (
    <div className="h-[600px] relative">
      <div className="absolute top-2 right-2 z-10 text-xs">
        {pageNumber} / {numPages}
      </div>
      <PDFSlickViewer viewerRef={viewerRef} usePDFSlickStore={usePDFSlickStore} />
    </div>
  );
}

Por que importa

Si necesitas un visor de PDF con UI propia, PDFSlick te ahorra el boilerplate de pdf.js y te da estado reactivo listo para componer. Lo guardo como recurso para no volver a armar un visor desde cero.

Referencias