0
Files
app/library/page.tsx
"use client";

import dynamic from "next/dynamic";

// embedpdf's plugin packages and the PDFium worker are browser-only, so the
// whole app is loaded client-side behind an `ssr: false` boundary.
const PdfLibraryApp = dynamic(
  () =>
    import("@/components/pdf-library-app").then(
      (mod) => mod.PdfLibraryApp,
    ),
  {
    ssr: false,
    loading: () => <div className="bg-muted h-full w-full" />,
  },
);

export default function Page() {
  return (
    // The library fills its container and scrolls inside itself, so pin an
    // explicit height here rather than letting the document grow the page.
    <div className="h-svh w-full overflow-hidden">
      {/* Three documents, so the grid opens on a shelf rather than a single
          card. */}
      <PdfLibraryApp
        documents={[
          { url: "/sample.pdf", name: "sample.pdf" },
          { url: "/form.pdf", name: "form.pdf" },
          { url: "/sample-with-attachments.pdf", name: "attachments.pdf" },
        ]}
      />
    </div>
  );
}

Every open document is a card in a grid — navigate its pages in place, then pick one to open it in a full-screen reader and jump back to the library. It renders every document off one engine with embedpdf's thumbnail plugin, after PDFSlick's multiple-documents example.