Skip to content

feat: add S3 file upload support via pushduck - #2554

Open
abhay-ramesh wants to merge 1 commit into
boxyhq:mainfrom
abhay-ramesh:feat/pushduck-file-uploads
Open

feat: add S3 file upload support via pushduck#2554
abhay-ramesh wants to merge 1 commit into
boxyhq:mainfrom
abhay-ramesh:feat/pushduck-file-uploads

Conversation

@abhay-ramesh

@abhay-ramesh abhay-ramesh commented Mar 27, 2026

Copy link
Copy Markdown

What

Adds authenticated file upload capability (images and documents) to the SaaS Starter Kit using pushduck (v0.4.0).

Files added/changed:

  • pages/api/upload/index.ts — upload API route with imageUpload and documentUpload handlers
  • components/FileUpload.tsxImageUpload and DocumentUpload React components (DaisyUI + Tailwind styled)
  • .env.example — AWS S3 environment variable stubs (Cloudflare R2 compatible)
  • package.json — adds pushduck@^0.4.0 dependency

Why

File upload is one of the most commonly needed features in SaaS applications (profile photos, attachments, documents). The starter kit currently has no file upload mechanism, so every team building on it has to wire this up from scratch.

How it works

pushduck uses the presigned URL pattern — the server generates a short-lived signed S3 URL, and the browser uploads directly to S3. This means:

  • No server bandwidth cost for file transfers
  • No file data touches your API server — only metadata
  • Files are gated behind a NextAuth session check in the middleware, so unauthenticated users cannot upload
  • Keys are namespaced by userId/timestamp/filename to avoid collisions

Environment variables required

AWS_S3_ACCESS_KEY_ID=
AWS_S3_SECRET_ACCESS_KEY=
AWS_S3_REGION=us-east-1
AWS_S3_BUCKET_NAME=

Cloudflare R2 is also supported — change the provider to "cloudflareR2" and add CLOUDFLARE_ACCOUNT_ID.

Usage example

import { ImageUpload, DocumentUpload } from '@/components/FileUpload';

// In any page or component:
export default function SettingsPage() {
  return (
    <div>
      <h2>Upload Profile Photo</h2>
      <ImageUpload />

      <h2>Upload Documents</h2>
      <DocumentUpload />
    </div>
  );
}

Test plan

  • Set the four AWS_S3_* env vars pointing to a real (or localstack) bucket
  • Sign in as any user
  • Navigate to a page using <ImageUpload /> — select a JPEG/PNG and confirm it uploads and returns a URL
  • Navigate to a page using <DocumentUpload /> — select a PDF and confirm upload
  • Confirm that hitting /api/upload without a session returns a 401
  • Confirm files appear in the S3 bucket under uploads/<userId>/<timestamp>/<filename>

Built with pushduck — a TypeScript-first S3 upload library for Next.js.

- Add /api/upload route with image and document upload handlers
- Add ImageUpload and DocumentUpload React components (DaisyUI styled)
- Files upload browser-to-S3 directly via presigned URLs (no server bandwidth)
- Auth-gated via NextAuth session in middleware
- Add AWS S3 env vars to .env.example (Cloudflare R2 compatible)
@vercel

vercel Bot commented Mar 27, 2026

Copy link
Copy Markdown

@abhay-ramesh is attempting to deploy a commit to the BoxyHQ Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant