SplitPDF is a static browser application for previewing and extracting PDF pages without uploading the document to a server.
I built SplitPDF to provide a small, inspectable alternative to PDF tools that require document uploads. The application reads a local PDF into browser memory, renders page previews, copies the requested pages into new documents, and downloads either a PDF or ZIP archive.
The core workflow lives in index.html; error-tracker.js and the Google Apps Script backend add feedback and error reporting without participating in PDF processing.
- Select individual, odd, even, all, or inverted page sets
- Export selected pages as one PDF
- Export every page as a separate PDF in a ZIP archive
- Define and export multiple custom page ranges
- Render page thumbnails and a keyboard-navigable full-page preview
- Drag page cards into a different workspace order
- Submit public or private feedback through the optional Apps Script integration
- Local document pipeline: the browser reads the source with
File.arrayBuffer(). PDF.js receives a copied byte array for rendering, while pdf-lib retains the original bytes for page extraction. The PDF itself is not posted by the splitting workflow. - Purpose-specific libraries: PDF.js handles rasterized previews, pdf-lib copies pages into new PDF documents, and JSZip packages multiple outputs. This keeps document manipulation on the client and avoids a custom server or build step.
- Explicit UI state: page order, selection, split mode, and custom ranges are held separately. Each export mode validates its own inputs and reports progress while generating files asynchronously.
- Download lifecycle: generated bytes become short-lived object URLs; the application triggers a browser download and immediately revokes each URL.
- Operational feedback loop: the frontend reports same-origin runtime failures and user feedback to a shared Apps Script endpoint. The tracker redacts email-shaped text, filters known third-party noise, deduplicates repeated errors, and enforces a per-session report budget.
- Backend guardrails: the Apps Script validates known application IDs, caps field lengths, drops honeypot submissions, separates feedback from errors, and excludes emails, private messages, and error rows from the public read endpoint.
- Static-site discoverability: canonical metadata, structured data,
robots.txt,sitemap.xml, andllms.txtare maintained alongside the application.
There is no automated test suite in the repository. Current verification is therefore manual in a browser, especially across the three export modes and the optional remote feedback path.
flowchart LR
A[Local PDF] -->|File API| B[Browser state]
B --> C[PDF.js previews]
B --> D[pdf-lib page extraction]
D --> E{One output?}
E -->|Yes| F[PDF download]
E -->|No| G[JSZip archive]
G --> H[ZIP download]
I[Feedback and runtime errors] -->|JSON only| J[Google Apps Script]
J --> K[Google Sheets]
The PDF pipeline stops at the browser download boundary. The Apps Script integration receives feedback and diagnostic metadata, not PDF bytes.
- HTML5, CSS, and vanilla JavaScript
- PDF.js 3.11.174 for parsing and rendering previews
- pdf-lib 1.17.1 for creating split PDFs
- JSZip 3.10.1 for multi-file archives
- Google Apps Script and Google Sheets for feedback and error storage
- Google Analytics via
gtag.js
The three PDF libraries are loaded from public CDNs, so the page needs network access when first loading them even though document processing is local.
No installation or build step is defined. Serve the repository root over HTTP with any static file server, then open index.html through that server. For example, if Python 3 is available:
python -m http.server 8000Then visit http://localhost:8000/ and choose a PDF. Internet access is required for the CDN-hosted libraries. The checked-in frontend already references a deployed feedback endpoint; deploying a replacement requires following the setup comments in google-apps-script/feedback-backend.gs and updating the endpoint values in index.html.
There are no repository-defined automated test or lint commands.
Live site: splitpdffree.com
Screenshot coming soon.
Active. The browser splitting workflow, static site, feedback integration, and error reporting are implemented. Automated tests and a checked-in screenshot are not present.
- Keeping sensitive-file processing local changes the architecture: rendering, transformation, packaging, and download management all need browser-safe implementations.
- Separating preview rendering from PDF mutation lets each library do one job and avoids coupling the visual page model to output generation.
- Client-side observability needs aggressive filtering, redaction, deduplication, and rate limits because browser extensions and third-party scripts produce noisy failures.
- A small serverless feedback backend still needs clear trust boundaries: validate inputs, limit stored payloads, and ensure private or diagnostic data cannot leak through public reads.