Set up Supabase
One free Supabase project holds your settings and your uploaded images. About three minutes, all in the dashboard.
Cubed keeps everything it owns in a single Supabase project:
| Half | What it holds |
|---|---|
| Postgres | Your admin panel settings, page text, colours, languages, rank tables, admin logins |
| Storage bucket | The images you upload — logo, favicon |
Nothing is written to the server's disk. That is why every host works the same way, why you do not need an S3 or R2 account, and why moving hosts is just pointing the new one at the same project.
Products, prices and payments are not here. They stay in Tebex and are read live on every page load. Your Supabase project stays tiny — a few hundred kilobytes.
Create the project
Sign up and make a project
Go to supabase.com, sign in, and click New project.
Pick a region near your players. Supabase generates a database password — copy it somewhere safe now. It is not shown again, and you need it in the next step.
The free tier is enough for this.
Copy the connection string
Project Settings → Database → Connection string, and choose the Session pooler tab.
Replace [YOUR-PASSWORD] with the password from step 1. That whole string is your
DATABASE_URI:
DATABASE_URI=postgresql://postgres.yourprojectref:yourpassword@aws-0-region.pooler.supabase.com:5432/postgresUse the Session pooler — port 5432. Supabase offers three strings and only one
of them works here. The next section explains why.
Copy the project URL and the service key
Two more values, both from Project Settings:
| Where | Value | Goes in |
|---|---|---|
| Data API → Project URL | https://yourprojectref.supabase.co | SUPABASE_URL |
API Keys → service_role | A long key | SUPABASE_SERVICE_ROLE_KEY |
SUPABASE_URL=https://yourprojectref.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_keyThe service_role key is a master key. It bypasses Supabase's row-level
security and grants full read/write access to your entire project — treat it like a
root password.
Never prefix it with NEXT_PUBLIC_, never commit it, never paste it in a screenshot
or a Discord message. If it leaks, rotate it in the Supabase dashboard immediately.
Create the storage bucket
Storage → New bucket. Name it media and turn Public bucket on.
That is the whole step — the theme is already configured to use it.
The bucket must be public. Your logo and favicon are shown to every visitor, so they have to be readable without a key. If the bucket is private, uploads succeed in the admin panel but the images 404 on the live site.
You can flip it later under Storage → your bucket → Settings.
Want a different name? Create it, then set SUPABASE_STORAGE_BUCKET to that name.
Otherwise the theme uses media.
Which connection string, and why it matters
This one detail causes more failed installs than anything else. Supabase shows you three strings:
| String | Looks like | Verdict |
|---|---|---|
| Session pooler | …pooler.supabase.com:5432 | ✅ Use this. Works over IPv4 and IPv6. |
| Direct connection | db.yourref.supabase.co:5432 | ❌ IPv6 only |
| Transaction pooler | …:6543 | ❌ Breaks the admin panel |
Direct connection resolves over IPv6 only. Most home broadband and plenty of VPS
providers have no IPv6 route, and the failure looks like a bare ECONNREFUSED
against an address full of colons — which reads like a server fault when it is
actually your network.
Transaction pooler (port 6543) breaks the prepared statements Payload relies
on, and cannot create your tables at all.
The theme warns you at start-up if it spots either of them in DATABASE_URI.
On the pooler your username is postgres.yourprojectref, not plain postgres.
Copy the whole string from the dashboard rather than hand-editing one you already
have.
What you should have now
Four values ready for your environment file:
DATABASE_URI=postgresql://postgres.yourref:yourpassword@aws-0-region.pooler.supabase.com:5432/postgres
SUPABASE_URL=https://yourref.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# SUPABASE_STORAGE_BUCKET=media ← only if you named the bucket something elseSUPABASE_URL is read at build time as well as run time — the build bakes your
Supabase hostname into the image loader and the Content-Security-Policy. On managed
hosts, set it before the first build, not after.
Backups
Everything worth backing up is in Supabase, so back up there:
- Database → Backups for your settings and page text
- Storage → your bucket for uploaded images
Your servers hold nothing but code. Wiping and rebuilding one loses no data.
Coming from an older version?
Versions before this one supported SQLite, Turso and MongoDB. Those are gone, and switching does not move your data.
Point DATABASE_URI at Supabase
Follow the steps above.
Build the tables
bun run seedRe-enter your settings and re-upload your images
Branding, colours, footer text and rank tables do not carry over. Do this before you go live.
Next
Put these values into your environment file: Environment variables.