A modern, fast, and 100% private web application built with Next.js that allows users to upload multiple images, reorder them, and convert them into a single, beautifully formatted A4 PDF document.
This application is designed with zero-knowledge architecture. All image processing and PDF generation occur entirely client-side (locally in the user's browser).
- No data leaves your device: Images are never uploaded to a backend server.
- No cloud storage: The resulting PDF is generated on-the-fly in your browser's memory and downloaded directly to your local machine.
- Drag & Drop Upload: Seamlessly drag and drop multiple images at once.
- Interactive Reordering: Drag images to reorder them before PDF conversion.
- Smart Scaling: Automatically calculates image aspect ratios to optimally fit and center them on standard A4-sized PDF pages.
- Premium UI: A sleek, glassmorphic dark-mode interface with micro-animations.
- Instant Generation: Click to convert and instantly download the generated PDF.
- Framework: Next.js (App Router)
- Library: React 18
- PDF Generation: jsPDF
- Drag & Drop functionality: @dnd-kit/core
- Icons: lucide-react
- Styling: Custom Vanilla CSS with CSS Modules
The application is structured as a Single Page Application (SPA) driven by Next.js.
The main entry point handles the overall layout and layout metadata. It wraps the core interactive component.
This component holds the entirety of the state and logic for the application:
- State Management: Manages the list of selected
images, theisGeneratingloading state, and theisCompletedsuccess state. - File Ingestion: Listens to
onDropand<input type="file">events. It uses the browser'sURL.createObjectURL()to instantly generate local preview URLs for the images without uploading them anywhere. - Drag & Drop Context: Utilizes
@dnd-kit'sDndContextandSortableContextto render a sortable grid of images (SortableItem.jsx). - PDF Generation: The
generatePDFfunction initializes a newjsPDFinstance. It iterates through the selected images, waits for them to load as HTMLImageobjects in memory, calculates the dimensions to fit them inside an A4 canvas (210x297mm), and draws them sequentially.
- User loads the app: The React app is hydrated in the browser.
- User selects images: The
handleFilesfunction filters for image formats and creates blob URLs for local previews. - User reorders (Optional): The
handleDragEndfunction updates the state array index based on the drag interaction. - User clicks "Convert": The app iterates over the images, calculates A4 dimensions, adds them to a
jsPDFinstance, and triggers the browser's native download dialog for the generated PDF. - Success State: The UI transitions to a success screen, offering a button to reset the state and start over.
First, clone the repository and install the dependencies:
npm installThen, run the development server:
npm run devOpen http://localhost:3000 with your browser to see the result.