# The delivery page

> The page your client opens: a preview, then approve or ask for changes. A Next.js template on your own bucket, with passwords, burn after download, resumable large uploads and signed webhooks. Try the demo, deploy it on Vercel.

Canonical: https://colis-site.vercel.app/en/drop · Markdown: https://colis-site.vercel.app/en/drop.md · Français: https://colis-site.vercel.app/drop

Drop a file, get a code, a link and a QR code. Your client opens it, sees the file, and approves it or asks for changes, while your page shows the answer as it comes. A Next.js template on your own bucket, deployed on Vercel from the repository.

- Try the demo: https://colis-tau.vercel.app
- The template on GitHub: https://github.com/mamadouwhile/colis/tree/main/templates/drop
- Read the README: https://github.com/mamadouwhile/colis/blob/main/templates/drop/README.md

## Two pages, and the routes between them.
The sending page, the pickup page, and the transfer routes with the receipt on top. Everything is yours to restyle.

- **Staged before it goes** — Picking a file shows what it is and a form: the lifetime, a password for this parcel, burn after the first download, the name it downloads under, the sending device, and a note of up to 280 characters. Nothing leaves the machine until you press send.
- **A shipping label** — The result prints the code on a label with a Code 39 barcode, the link to share, and a QR code of that link for a phone.
- **The pickup page** — `/K7QP2M4X` shows the file before anything is saved: an image, a video, audio, a PDF, the first lines of a text. Then what is known about it: the size, the type, the time left, the sender’s note.
- **Approve or ask for changes** — Under the preview, one question: does the file match what was expected? Approve the delivery, or ask for changes and say which, in up to 1,000 characters. One answer, final.
- **Your tracking** — Your sending page follows the receipt on its own: sent, opened, then the verdict, stamped « Validé » or « À corriger », with the client’s comment.
- **Large files, resumable** — Above `DROP_MAX_SIZE_MB`, the browser uploads straight to your bucket in 8 MiB parts, up to `DROP_MAX_UPLOAD_MB`, and picks an interrupted upload up where it stopped.

## Five variables, one lifecycle rule.
Until the @colis packages are on npm, the page builds from the monorepo: import the whole repository on Vercel, not the template folder alone.

**the environment**
```sh
COLIS_BUCKET=livraisons
COLIS_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
COLIS_REGION=auto
AWS_ACCESS_KEY_ID=…
AWS_SECRET_ACCESS_KEY=…

# optional
DROP_PASSWORD=…              # asked before an upload, never for a pickup
DROP_EXPIRES_IN=86400        # the default lifetime, in seconds
DROP_MAX_EXPIRES_IN=604800   # the longest a sender may choose
DROP_MAX_SIZE_MB=4           # through the function, under Vercel's limit
DROP_MAX_UPLOAD_MB=2048      # above that, straight to the bucket, in parts
DROP_WEBHOOK_URL=…           # where the signed events go
DROP_WEBHOOK_SECRET=…        # and what signs them
```

1. Create a bucket on R2, S3, Scaleway, Wasabi or a MinIO you host, and a key pair with read and write on that bucket and nothing else.
2. On Vercel, Add New → Project and pick the repository. Set the Root Directory to `templates/drop` and leave “Include files outside the root directory” on: its `vercel.json` installs with Bun at the root and builds the packages first.
3. Paste the five variables, and `DROP_PASSWORD` so strangers cannot fill your bucket.
4. Add a lifecycle rule that deletes objects under the prefix (`drop/` by default) after a day or two, and a CORS rule for large files.
5. Run `colis verifier --remote https://your-deployment.vercel.app/api/transfers --token <password>` and watch it round-trip a real parcel.

**or run it locally**
```sh
git clone https://github.com/mamadouwhile/colis.git && cd colis
bun install && bun run build
cp templates/drop/.env.example templates/drop/.env.local   # point it at a bucket
bun run --filter colis-drop dev                               # http://localhost:3400
```

## What it does not do.
- **No accounts, no history** — A code is a bearer token with an expiry. There is no list of past parcels; each one’s receipt lives as long as the deployment’s longest lifetime.
- **One file per code** — Zip a folder first. From a terminal it is one line: `tar cz ./dir | colis envoyer - --name dir.tar.gz`.
- **A preview costs a download** — The bytes come through the function either way, so `DROP_PREVIEW_MAX_MB` caps it and `DROP_PREVIEW=false` turns it off. Uploaded files are never served as a page this origin would run.
