ShipStatic ShipStatic

Where to Host Your Supabase Frontend in 2026

You finished the hard part. Then the easy part took two hours. Here is why deploying a Supabase app is smaller than you were told.

You already have a backend

Open the folder your build just made. It is probably called dist.

Inside it: an index.html, some JavaScript, some CSS, a few images. That is the whole thing. There is nothing in that folder that needs a server running when a visitor arrives. No Node process. No runtime. Nothing to keep warm.

That is not a limitation. It is what happened when you chose Supabase. Your database, your auth, your file storage and your secrets are already hosted, on Supabase's servers, behind a URL. The backend got taken care of before you ever thought about deploying.

So the question is not where do I host my app. Half of it is hosted. The question is where to put a folder of files so that people can open it.

Why every tutorial says otherwise

Because for about five years, it was true.

Around 2016 the industry got excited about exactly this idea: a static frontend talking to hosted APIs. It half worked. The API half wasn't ready. You still needed a server of your own to hold secrets, run auth, and talk to a database. So everyone went the other way, server-side rendering took over, and "deploy it to a platform that runs your code" became the reflex answer to every question about publishing a website. For most stacks at the time, it was the right answer.

Then the API half actually arrived. Supabase gave you Postgres, auth, storage, realtime and a place to put secrets, all behind a single URL. The split that didn't work in 2016 works now, and a large share of the apps being built today are built on it.

The defaults never moved back. The advice you got is a fossil of a real constraint that stopped existing. Nobody was wrong. The ground moved and the tutorials didn't.

What an oversized platform actually costs you

Not money, usually. Most free tiers cover a project like yours.

It costs you the ability to tell what went wrong.

When your app misbehaves, you need to work out whether it is your code, your build, your host, or Supabase. Every system in that list is a suspect you have to rule out, and ruling one out takes a vocabulary you may not have yet. Framework presets. Function regions. Runtime versions. Environment variable scoping. Build caches. None of those things exist in your app. They exist in the platform you put it on.

Take the runtime out and the list gets shorter. If the host does nothing but serve files, then the host cannot be the reason your data is missing. It is either your code or your Supabase policies, and now you are debugging two things instead of four.

That is the argument for a static host. Not that it is faster or cheaper. That it is one fewer thing that can be wrong.

Four things that are true about deploying a Supabase frontend

These are true wherever you host. They are worth knowing before you deploy rather than after.

1. Row Level Security is your actual security boundary

Supabase publishes your tables over HTTP, using the same anon key that ships inside your JavaScript bundle. That key is public by design and that is fine. What defends your data is Row Level Security, and RLS is the one part of the stack that does not do itself.

Here is the part that catches people. Your app looks identical whether your policies are right or wrong. Nothing breaks. Nothing warns you. That is what makes it the bug that ships. Turn RLS on for every table, write the policies, and then try reading a row you shouldn't be able to read.

2. When you need server code, you already have somewhere to run it

Sooner or later something has to happen off the browser. A Stripe secret key that cannot go in your build. A webhook Stripe needs to POST to. A scheduled job. A call to a third-party API that must be trusted rather than merely hidden. Anything in your dist folder is readable by anyone who opens the network tab, so none of this can live there.

That is what Supabase Edge Functions are. They run on Supabase's servers, hold their own secrets, sit next to your database, and your frontend calls them like any other endpoint. Writing one does not change what your frontend is. It is still a folder.

This is the moment people reach for a full-stack host, and it is the moment they least need to. Needing a backend endpoint is not the same as needing your frontend and your backend to ship from the same vendor.

Take payments, since that is usually the first time it comes up. Adding Stripe to a Supabase app is two Edge Functions. One creates the Checkout Session: your frontend calls it, it holds the secret key, it returns a URL you send the customer to. One receives Stripe's webhook and writes the result into your own tables, so your app knows who paid. Your frontend gains a button and keeps being a folder.

Two things to get right while you are there, because both are quiet failures. Edge Functions verify the Supabase JWT by default and Stripe's webhook does not carry one, so you will turn that off for the webhook function. Verifying Stripe's own signature instead is not optional at that point: without it, anyone who finds the URL can post a fake payment event and give themselves a subscription. And the table the webhook writes to is one your users can also read, so its Row Level Security has to let them read their own row and never write it. Which brings you back to the first item on this list.

3. The VITE_ prefix means public

Vite only exposes environment variables that start with VITE_, and exposing them means baking them into the bundle. Your Supabase URL and anon key belong there. Your service role key never does. If you find yourself adding the prefix to make something work, stop and check which of the two you are holding.

4. Client-side routing needs a catch-all, or refreshing breaks

This is the one that makes people think their deployment is broken. Your app works, you navigate to /dashboard, you hit refresh, and you get a 404. Nothing is wrong with your code. The browser asked the server for a file called dashboard, and your build only ever made index.html. React Router does the rest in the browser, but the browser never got that far.

Every static host can fix this with a rewrite rule. Most of them make you write it.

What ShipStatic does with that folder

You give us the folder. We serve it from a global edge network. You get a URL.

We do not run your code, so we do not need to know which framework made it. There is no build step on our side, no framework detection, and no project settings to get wrong.

SPA routing is automatic. We look at your index.html and recognise a single-page app. If it is one, the catch-all rewrite is added for you, at upload time, with no config file. Refreshing a route just works. If you want to control it yourself, a ship.json in your folder wins.

Build wherever you like. On your laptop, in CI, or from an AI tool. npm run build then ship ./dist. That is the whole deployment.

Flat pricing, unlimited bandwidth. Free to start, then from $4.99/mo. Not per seat, not per build minute, and never metered against traffic. Your bill does not become a surprise if your app gets shared somewhere.

Immutable deployments. Every upload is a permanent snapshot with its own URL. Point your domain at any previous one instantly, which is the rollback you want at the moment you need it.

Custom domains with automatic HTTPS. Add a subdomain, set one DNS record, done. Certificates are provisioned and renewed without you.

Eight ways to deploy. Web dashboard, CLI, SDK, REST API, MCP, GitHub Action, n8n, or an agent skill. If you build with Claude, Cursor or another agent, it can publish the site itself.

This page is for you if...

  • Your frontend is Vite, React, Vue, Svelte or plain HTML, with no server rendering
  • Supabase handles your database, auth and storage
  • Anything needing a secret lives in an Edge Function
  • You built it with Lovable, Bolt, v0, Cursor or an AI assistant

It is not for you if...

  • You are running Next.js with server components or server actions
  • You need server-side rendering for SEO on public pages
  • Your app depends on serverless functions living beside the frontend
  • You want preview deployments tied to Git branches

If you are in the second column, use a full-stack platform. Genuinely. Those are good products doing a job we do not do.

Common questions

Is my Supabase app really static?

Check it yourself. Run your build and look in the output folder. If it contains HTML, JavaScript, CSS and images, and no server code, it is static. A Vite or Create React App project always produces this. Having a login screen does not change it: authentication happens in the browser against Supabase.

Where do my Supabase environment variables go?

Into your build, wherever you run it. Your project URL and anon key are compiled into the bundle by Vite when you build, so they are already inside the folder by the time you upload. We never need them, and there is no environment variable screen to fill in. Your service role key stays in Supabase, on your Edge Functions.

Do I need to configure SPA routing?

No. We inspect your index.html at upload time and add the catch-all rewrite when it is a single-page app. If you would rather be explicit, include a ship.json with your own rewrites and it takes precedence.

What if I need a real backend endpoint later?

Write a Supabase Edge Function. That is a real backend endpoint, running on a server, holding secrets, sitting next to your database. Taking Stripe payments, for example, is two of them: one to create the Checkout Session, one to receive the webhook. Your frontend calls them over HTTPS and stays a folder of static files, so nothing about your hosting has to change.

What about Firebase, Convex or Pocketbase?

Same shape, same answer. Any backend that lives behind a URL leaves you with a static frontend. Nothing on this page is specific to Supabase except the names.

Can an AI agent deploy for me?

Yes. We publish an MCP server, so Claude, Cursor and other MCP-capable assistants can upload your build and hand you back the URL. There is also a CLI, an SDK, a GitHub Action and an agent skill. See hosting for AI agents.

Your backend is running. Ship the rest.

Free to start. No credit card required.