From 59c8a7fa2c9ec626e4f60d5bd9f95d809b444fa2 Mon Sep 17 00:00:00 2001 From: anirudh7065 Date: Sun, 12 Oct 2025 14:37:29 +0530 Subject: [PATCH 1/3] Added a PDF viewer snippet --- .../PDF viewer page in tsx/PdfViewer.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts diff --git a/Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts b/Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts new file mode 100644 index 0000000000..a890f0eb9f --- /dev/null +++ b/Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts @@ -0,0 +1,62 @@ +"use client"; +import { getDocument, GlobalWorkerOptions } from "pdfjs-dist/legacy/build/pdf.mjs"; +import { useEffect, useRef } from "react"; + +GlobalWorkerOptions.workerSrc = "/pdfjs/pdf.worker.min.mjs"; + +export default function PdfViewer({ file }: { file: File }) { + const containerRef = useRef(null); + const hasRendered = useRef(false); + + useEffect(() => { + if (!file || file.size === 0) return; + if (hasRendered.current) return; + + hasRendered.current = true; + const container = containerRef.current; + if (!container) return; + + const renderPDF = async () => { + container.innerHTML = ""; + + // Render PDF + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + + // Render each page + for (let i = 1; i <= pdf.numPages; i++) { + // Render page + const page = await pdf.getPage(i); + const viewport = page.getViewport({ scale: 1.2 }); + + // Create canvas + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d")!; + canvas.height = viewport.height; + canvas.width = viewport.width; + + // Render page + await page.render({ canvasContext: context, viewport }).promise; + + // Add canvas to container + canvas.id = `page_${i}`; + container.appendChild(canvas); + } + }; + // Render PDF + renderPDF(); + + return () => { + // Clear on unmount + if (container) container.innerHTML = ""; + }; + }, [file]); + + return ( + // Render PDF +
+ ); +} From 9ab8bb8178e0ec3b8538cf217453ef63d24cecf5 Mon Sep 17 00:00:00 2001 From: anirudh7065 Date: Sun, 12 Oct 2025 15:00:42 +0530 Subject: [PATCH 2/3] Added Readme.md file for PDF viewer component --- .../UI Pages/PDF viewer page in tsx/Readme.md | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 Client-Side Components/UI Pages/PDF viewer page in tsx/Readme.md diff --git a/Client-Side Components/UI Pages/PDF viewer page in tsx/Readme.md b/Client-Side Components/UI Pages/PDF viewer page in tsx/Readme.md new file mode 100644 index 0000000000..e7f5656b8e --- /dev/null +++ b/Client-Side Components/UI Pages/PDF viewer page in tsx/Readme.md @@ -0,0 +1,182 @@ +# 📄 PDF Viewer Component + +A lightweight client-side **React PDF viewer** built with **pdf.js**, designed to render and display uploaded PDF files seamlessly inside your web app. + +--- + +## 🚀 Features + +* ⚡ **Client-side rendering** — No server dependency +* 📚 **Multi-page support** — Renders every page dynamically +* 🧠 **Efficient memory use** — Prevents redundant re-rendering +* 🧩 **Easy integration** — Drop into any React or Next.js app +* 🎨 **Customizable container** — Style with Tailwind or CSS + +--- + +## 🧱 Tech Stack + +* **React / Next.js** (client component) +* **pdfjs-dist** (`pdf.js` library for parsing and rendering PDFs) +* **TypeScript** + +--- + +## 📦 Installation + +```bash +# Using npm +npm install pdfjs-dist + +# OR using yarn +yarn add pdfjs-dist +``` + +--- + +## 🧩 Usage + +### 1. Add the worker file + +You need the PDF.js worker file (`pdf.worker.min.mjs`) to be available in your public folder. + +**Structure:** + +``` +/public/pdfjs/pdf.worker.min.mjs +``` + +You can get it from: + +``` +node_modules/pdfjs-dist/build/pdf.worker.min.mjs +``` + +--- + +### 2. Import and use the component + +```tsx +"use client"; +import PdfViewer from "@/components/PdfViewer"; +import { useState } from "react"; + +export default function Page() { + const [file, setFile] = useState(null); + + return ( +
+ { + const selectedFile = e.target.files?.[0]; + if (selectedFile) setFile(selectedFile); + }} + /> + + {file && } +
+ ); +} +``` + +--- + +## 🧠 Component Details + +### **File:** `PdfViewer.tsx` + +```tsx +"use client"; +import { getDocument, GlobalWorkerOptions } from "pdfjs-dist/legacy/build/pdf.mjs"; +import { useEffect, useRef } from "react"; + +GlobalWorkerOptions.workerSrc = "/pdfjs/pdf.worker.min.mjs"; + +export default function PdfViewer({ file }: { file: File }) { + const containerRef = useRef(null); + const hasRendered = useRef(false); + + useEffect(() => { + if (!file || file.size === 0) return; + if (hasRendered.current) return; + + hasRendered.current = true; + const container = containerRef.current; + if (!container) return; + + const renderPDF = async () => { + container.innerHTML = ""; + + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + + for (let i = 1; i <= pdf.numPages; i++) { + const page = await pdf.getPage(i); + const viewport = page.getViewport({ scale: 1.2 }); + + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d")!; + canvas.height = viewport.height; + canvas.width = viewport.width; + + await page.render({ canvasContext: context, viewport }).promise; + + canvas.id = `page_${i}`; + container.appendChild(canvas); + } + }; + + renderPDF(); + + return () => { + if (container) container.innerHTML = ""; + }; + }, [file]); + + return ( +
+ ); +} +``` + +--- + +## 🎨 Styling Example (Optional) + +```css +.pdf-container { + background-color: #f9f9f9; + padding: 1rem; + border-radius: 12px; + display: flex; + flex-direction: column; + gap: 1rem; +} +canvas { + border: 1px solid #ddd; + border-radius: 8px; +} +``` + +--- + +## ⚠️ Notes + +* Make sure the **PDF.js worker file path** matches: + + ```ts + GlobalWorkerOptions.workerSrc = "/pdfjs/pdf.worker.min.mjs"; + ``` +* This component renders each page on a separate ``. +* For large PDFs, consider lazy loading or pagination to improve performance. + +--- + +## 🧑‍💻 License + +This component is released under the **MIT License** — free to use and modify in your projects. From a5e32e1db37b59d5d042ac61986eeab472571a4f Mon Sep 17 00:00:00 2001 From: anirudh7065 Date: Sun, 12 Oct 2025 15:08:44 +0530 Subject: [PATCH 3/3] Changed the extension to js --- .../PDF viewer page in tsx/{PdfViewer.ts => PdfViewer.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Client-Side Components/UI Pages/PDF viewer page in tsx/{PdfViewer.ts => PdfViewer.js} (100%) diff --git a/Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts b/Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.js similarity index 100% rename from Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.ts rename to Client-Side Components/UI Pages/PDF viewer page in tsx/PdfViewer.js