A Cloudflare Worker that streams one PDF resume from a private R2 bucket, renders it in the browser, and provides a forced-download link.
| Route | Purpose |
|---|---|
/ |
Responsive resume viewer |
/resume.pdf |
Inline PDF response |
/download |
PDF response with Content-Disposition: attachment |
The existing pitrick-cdn-resources R2 bucket can remain private. Resumes are stored under its Resume/ prefix (displayed as a directory in the Cloudflare dashboard). The Worker exposes only the object named by RESUME_OBJECT_KEY; it does not provide bucket listing or arbitrary object access.
-
Install dependencies and authenticate Wrangler:
npm install npx wrangler login
-
Upload the resume into the
Resume/directory of the existing bucket:npx wrangler r2 object put pitrick-cdn-resources/Resume/resume.pdf --file="./resume.pdf" --content-type="application/pdf"
-
Deploy:
npm run deploy
Wrangler will print the deployed workers.dev URL.
Edit wrangler.jsonc to change:
bucket_name: the existing R2 bucket containing the PDF. It is set topitrick-cdn-resources.RESUME_OBJECT_KEY: the exact key of the PDF inside R2. Resume files should remain under theResume/prefix.RESUME_FILE_NAME: the filename visitors receive when downloading.RESUME_TITLE: the title displayed above the viewer.
To serve a different resume, upload it under Resume/ and update RESUME_OBJECT_KEY to its complete key, such as Resume/patrick-lim-resume.pdf.
Wrangler uses local R2 storage by default. Upload a local test object, then start the Worker:
npx wrangler r2 object put pitrick-cdn-resources/Resume/resume.pdf --file="./resume.pdf" --content-type="application/pdf" --local
npm run devTo use the real bucket while developing, add "remote": true to the R2 binding in wrangler.jsonc, then run npm run dev.
npm run checkThis performs strict TypeScript checking and a Wrangler dry-run build.
CI/CD uses Cloudflare Workers Builds and the Cloudflare Workers and Pages GitHub App. There are no GitHub Actions workflows or Cloudflare credentials stored in GitHub.
After pushing this repository to GitHub:
-
Open the
resume-viewerWorker in the Cloudflare dashboard. -
Go to Settings > Builds and select Connect.
-
Install or authorize the Cloudflare Workers and Pages GitHub App for this repository.
-
Select the GitHub repository and configure:
Setting Value Production branch mainBuild command pnpm run typecheckDeploy command pnpm exec wrangler deployNon-production branch command pnpm exec wrangler deploy --dry-run --outdir=distRoot directory / -
Save the build settings. Future pushes to
mainwill be validated and deployed by Cloudflare.
Cloudflare manages the deployment token for Workers Builds. Because workers_dev and preview_urls are disabled, non-production branches perform validation without publishing a preview URL. Configure the Worker's production route or custom domain in Cloudflare before relying on the deployed endpoint.
- The PDF body is streamed from R2 instead of being buffered in Worker memory.
- Single byte ranges (
Range: bytes=...) are supported for browser PDF viewers. ETagandLast-Modifiedare returned for efficient revalidation.- A styled, non-cacheable placeholder is shown when the configured resume does not exist.
- Security headers and a restrictive Content Security Policy are applied.
- The R2 object is forced to
application/pdfand the configured download filename is sanitized.