File uploads in your app
When people using your app need to upload something — a product photo, an avatar, a PDF invoice — those files need somewhere to live. Turning on storage gives your project that place, and gives the AI a helper it knows how to use.
This is different from attaching files to a prompt. Those are inputs you hand the AI while building. These are files your users upload while using the finished app.
Turning it on
Open Settings → Storage and choose Enable file storage. Three things happen:
- Your project gets two new files,
lib/storage.tsandlib/image-compress.ts. They are maintained by Poleved, so you never have to edit them. - Your project gets a storage token, added to its environment variables automatically. You do not need to copy or paste it anywhere.
- Uploads start counting against your project's storage quota.
After that, just ask for the feature: "let customers upload a photo with their review". The AI uses the helper rather than inventing its own uploader.
What happens to an image
Images are compressed on the way in, before anything is stored or counted:
- Photos are shrunk so the longest side is at most 2560 pixels. On a phone photo this is where nearly all the saving comes from.
- Quality is reduced to 80%, which is normally invisible.
- Rotation is applied properly, so a photo taken sideways is stored the right way up.
- Location data is stripped. A phone photo carries the GPS coordinates of where it was taken, and those should not travel with a product picture.
- Transparent images stay transparent — a logo with a see-through background does not come back with a black box behind it.
Two safeguards you do not have to think about: if compressing would make a file bigger (which happens with already-optimised images), the original is kept; and if the result would not open properly, the original is kept.
PDFs, spreadsheets, CSVs and GIFs are stored exactly as they arrive. Compression only applies to still images, because "reduce the quality" is not a thing you can do to a PDF without breaking it.
If a feature genuinely needs the untouched original, say so in your prompt — the helper can skip compression per upload.
Uploaded files are public
Anyone who has the link to an uploaded file can open it. There is no password on it.
The links are impossible to guess — they use a random ID, never the original filename — so a file is only reachable by someone you gave the link to, or someone who found it in your app. That is the right trade for product photos, avatars and public documents.
It is the wrong trade for anything private. Do not use this for ID documents, contracts, medical records or anything else that would matter if it leaked. Poleved does not currently offer private, access-controlled file storage.
Filenames are also not kept in the link, which is deliberate: people name files things like invoice-budi-santoso.pdf.
Limits
| Limit | Value |
|---|---|
| Total per project | 10 MB |
| Largest single stored file | 10 MB |
| File types | Images (PNG, JPEG, WebP, GIF), PDF, spreadsheets, CSV, JSON, YAML, Markdown, plain text |
10 MB is roughly 20–40 web images after compression. It is deliberately small for now — a larger paid allowance is planned.
The Settings → Storage page shows a usage bar so you can see where you stand. It turns amber at 80% and red when full. Once full, new uploads are rejected with a clear message rather than failing silently — but your app keeps working and existing files stay online.
To free space, delete files from the same page. Deleting a project deletes its files with it.
SVG files are not accepted. An SVG is really a small program, and one uploaded to a site can run code in it — so it is excluded on purpose. Convert to PNG first.
Using your own storage instead
You can point your app at your own S3-compatible bucket — Amazon S3, Cloudflare R2, MinIO, or anything that speaks the same protocol. Add these under Publish → Env Variables:
S3_ENDPOINT
S3_BUCKET
S3_ACCESS_KEY_ID
S3_SECRET_ACCESS_KEY
S3_PUBLIC_BASE
Your app then writes to your bucket instead, and stops counting against the Poleved quota. Nothing in your code changes — it is the same helper, reading different settings.
This is also the portable option. An app using Poleved storage calls back to Poleved to upload, so if you export it and host it yourself, that part stops working. An app using your own bucket does not depend on us at all.
After exporting your project
Exporting copies your code, not your files. Files already uploaded stay where they are and their links keep working.
The exported copy still holds your storage token, so it can keep uploading into your Poleved quota. If you have moved on and do not want that, open Settings → Storage and choose Revoke & regenerate. The old token stops working immediately; files already uploaded stay online.
When something goes wrong
| What you see | What it means |
|---|---|
| "Storage is full" | You hit the 10 MB project limit. Delete files in Settings → Storage. |
| "File too large" | One file exceeded the size limit, even after compression. |
| "Files of type … are not accepted" | The format is not on the allowed list above. |
| Upload works, file does not display | Storage may not have a public address connected yet — Settings → Storage says so at the top if that is the case. |
| Files disappear after publishing | Your app is writing files to disk instead of using storage. Ask the AI to use lib/storage.ts; each publish starts a fresh container, so anything written to disk is lost. |