Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/S4nti4goCoder/cloudsyncpro/llms.txt

Use this file to discover all available pages before exploring further.

CloudSyncPro stores all user files in Cloudflare R2 — an S3-compatible object store with no egress fees. Files are never uploaded through Supabase; instead, the upload-file Edge Function generates a short-lived presigned URL and the browser uploads directly to R2, keeping bandwidth costs low and upload speeds high.
1

Create an R2 bucket

  1. Log in to the Cloudflare dashboard and select your account.
  2. Go to R2 Object Storage and click Create bucket.
  3. Give the bucket a name (e.g. cloudsyncpro). Note the name — it maps to R2_BUCKET_NAME in your Edge Function secrets.
  4. Leave the default region setting (Cloudflare distributes R2 globally).
Cloudflare R2 has a generous free tier: 10 GB storage, 1 million Class A operations (writes), and 10 million Class B operations (reads) per month. For most early-stage deployments this is more than enough before incurring any charges.
2

Configure the CORS policy

The browser uploads files directly to R2, so the bucket must allow cross-origin requests from your production domain.In R2 → your bucket → Settings → CORS Policy, add the following configuration:
[
  {
    "AllowedOrigins": ["https://your-domain.com"],
    "AllowedMethods": ["GET", "PUT", "HEAD"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 3600
  }
]
Replace https://your-domain.com with your actual Vercel deployment URL. During local development you can add http://localhost:5173 as a second entry in AllowedOrigins.
3

Generate R2 API credentials

  1. In the Cloudflare dashboard go to R2 → Manage R2 API Tokens.
  2. Click Create API Token.
  3. Grant Object Read & Write permissions scoped to your bucket.
  4. Copy the Access Key ID and Secret Access Key — they are shown only once.
  5. Note your Cloudflare Account ID (visible in the right-hand sidebar of the dashboard).
Your R2 S3-compatible endpoint is:
https://<account-id>.r2.cloudflarestorage.com
Set these four values as Edge Function secrets in Supabase (R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME). See Configure Supabase for details.
4

Set the public bucket URL

The frontend uses VITE_R2_PUBLIC_URL to construct read URLs for stored files (images, PDFs, etc.). You have two options:Option A — pub.r2.dev (quickest)Enable the public access URL in R2 → your bucket → Settings → Public Access. Cloudflare assigns a URL in the form https://pub-<hash>.r2.dev. Use that as VITE_R2_PUBLIC_URL.Option B — Custom domain (recommended)In R2 → your bucket → Settings → Custom Domains, attach a domain you control (e.g. files.your-domain.com). Then set:
VITE_R2_PUBLIC_URL=https://files.your-domain.com
Using a custom domain on the same root domain as your app (e.g. files.your-domain.com alongside your-domain.com) avoids cross-origin cookie restrictions, enables HTTP/2 connection reuse, and makes it easier to add a CDN cache layer in front of R2 later — all of which improve file load performance for end users.

How the upload flow works

Understanding the upload flow helps when debugging permissions or CORS errors:
  1. Client requests a presigned URL — the browser calls the upload-file Supabase Edge Function, passing the filename, MIME type, workspace ID, and parent folder.
  2. Edge Function validates and signs — the function checks the user’s workspace permissions via the Supabase service role, then generates a time-limited R2 presigned PUT URL using the R2 API credentials.
  3. Client uploads directly to R2 — the browser PUTs the file binary straight to the presigned URL. This request goes directly to Cloudflare and never passes through Supabase, saving bandwidth and avoiding the 6 MB Supabase Edge Function body limit.
  4. Client registers the file in Postgres — after a successful PUT, the browser calls the Supabase API to insert a record into the files table with the R2 object key, size, and metadata.
Browser  ──(1) POST /functions/v1/upload-file──►  Supabase Edge Function
Browser  ◄──(2) presigned PUT URL ────────────────  Supabase Edge Function
Browser  ──(3) PUT <binary> ──────────────────────► Cloudflare R2
Browser  ──(4) INSERT into files ─────────────────► Supabase Postgres
If step 3 fails with a CORS error, re-check that AllowedOrigins in the R2 CORS policy exactly matches the origin your app is served from (including the https:// scheme and no trailing slash).

Build docs developers (and LLMs) love