Skip to content
DocsFrontendDeploying a Frontend

Deploying a Frontend

PocketBase Cloud hosts single-page applications with HTTPS and a dedicated subdomain — ideal for the frontend of the app whose data lives in your PocketBase instance. Build your SPA with React, Vue, Svelte, Vite, or another client-side tool that produces an index.html entry point and static assets.

All plans include frontend hosting (5 frontends on Free and Starter, unlimited on Pro).

There are two ways to ship one: upload a ZIP in the portal, or run pb cloud frontend deploy in the project directory. The CLI path runs your build, packages the output, and uploads it in one command.

Build-time configuration

Whichever path you take, your PocketBase URL is baked in at build time — frontends have no server-side environment store:

VITE_POCKETBASE_URL=https://<instance-name>.pocketbasecloud.com npm run build

Step 1: Build your site

npm run build

This produces a folder containing your SPA entry point and static assets — typically dist/ for Vite projects or build/ for Create React App.

The CLI runs this step for you as part of deploy, so you only need it by hand for the portal path or to check the output before shipping.

Step 2: Deploy

Using the portal

  1. Open your project and go to the Frontends tab
  2. Click New Frontend, enter a name (this becomes the subdomain), and click Create
  3. Zip the contents of your build output folder — the ZIP should contain index.html at its root, not dist/index.html
  4. On the frontend’s Deploy page, upload the ZIP and click Deploy

Using the CLI

cd web
pb cloud frontend deploy --name web

That single command runs the build, zips the output directory, uploads it, creates the frontend if it doesn’t exist, and waits for it to come up.

pb cloud deploy --name web does exactly the same thing: it recognises a static site — by its vite/svelte/vue/angular config, a bundler dependency, or an index.html — and runs this command for you. See One deploy command for all three.

Flag What it does
--name <name> Which frontend to deploy. Asked for when omitted and nothing is linked.
--subdomain <sub> Address to serve a new site from. Defaults to the name.
--skip-build Package the output directory without rebuilding
--zip <file> Upload an archive you built yourself
--location <loc> Region for the deployment (Starter)
--compute <id> Compute to deploy onto. Asked for on Pro, and in an organization’s project, when there is more than one. List them with pb cloud compute ls. (Formerly --server, still accepted.)
--env <name> Which pb.json environment to target

Step 3: Redeploy

Using the portal

Build and zip again, then upload the new archive on the frontend’s Deploy page — same flow as the first time.

Using the CLI

The first deploy records the frontend in web/pb.json, so afterwards:

pb cloud frontend deploy    # rebuild + redeploy the linked site

How the CLI build is configured

The build command and output directory are inferred from your project (Vite, SvelteKit, Angular, Next.js config, or the build script in package.json) and written into pb.json on the first deploy. Review the guess before anything ships with:

pb cloud init frontend
// web/pb.json
{
  "projectId": "dhs4xnprgplurvo",
  "kind": "frontends",
  "defaultEnvironment": "production",
  "environments": {
    "production": { "id": "…", "name": "web" }
  },
  "build": {
    "command": "npm run build",
    "outputDir": "dist"
  }
}

Edit that block whenever the guess is wrong — it is never overwritten. Add exclude globs to drop files from the ZIP. .git, pb_data, .DS_Store, .env, .env.*, *.log, and node_modules are always excluded.

Staging and production from one directory

pb cloud frontend deploy --name web-staging --env staging  # creates + links
pb cloud environments                                      # what this dir targets
pb cloud frontend deploy --env staging                     # from now on, no flags

Each environment is its own frontend in the same project — in the portal they appear as two separate frontends, which is exactly what they are. A pb.json environment can override the build command:

{
  "environments": {
    "production": { "id": "…", "name": "web" },
    "staging": {
      "id": "…",
      "name": "web-staging",
      "build": { "command": "npm run build:staging" }
    }
  }
}

Your site is live

Provisioning takes under a minute. Your site is then live at:

https://<frontend-name>.pocketbasecloud.com

Check on it from the Frontends tab in the portal, or from the terminal:

pb cloud frontend ls
pb cloud frontend info --name web

Frontends are static files, so there are no container logs to stream — on either path, a failed page load is a build or routing problem, not a runtime one.

Custom domains

Using the portal

Add and verify a custom domain from the frontend’s detail page.

Using the CLI

pb cloud frontend domain add app.example.com --name web
pb cloud frontend domain verify app.example.com --name web
pb cloud frontend domain remove app.example.com --name web

Single-page app routing

Client-side routers such as React Router and Vue Router handle navigation in the browser. PocketBase Cloud falls back every application route to index.html, so deep links like /dashboard/settings load your SPA and let the client-side router render the correct screen.

Talking to PocketBase from the browser

Your frontend calls the PocketBase instance directly — see Connecting Your App. Both services are served over HTTPS on the same platform, so there are no mixed-content or certificate issues to deal with.

Remember that anything shipped to the browser is public: the instance URL is fine to expose, and per-user data protection belongs in your collection’s API rules, not in frontend code.

Full-stack in one project

A typical production setup on PocketBase Cloud is one project containing:

  • a PocketBase instance — database, auth, files
  • a frontend — your static UI
  • optionally a backend — server-side code for payments, webhooks, or server-rendered pages (Pro plan)

Templates on the Projects page scaffold that whole stack in one click. From the CLI it’s one directory per resource, each linked once:

cd db   && pb cloud pb deploy --name my-app-db
cd ../api && pb cloud backend deploy --name my-app-api
cd ../web && pb cloud frontend deploy --name my-app-web

Next steps