Skip to content
Free Templates — Issue Nº 01

Setup guide

An idempotent, no-nuke setup. Five steps take you from a cloned template to a live, admin-controlled site backed by Convex.

You never delete the Convex project

Every step here is safe to repeat. If something is misconfigured — a wrong env var, a missing key, a half-finished deploy — the fix is to re-run these steps, not to delete and recreate the Convex project. The build only writes what is missing, so re-running converges to a correct state instead of starting over.

  1. Grab your Convex URL + a full-permission deploy key

    In the Convex dashboard, open your project and copy the deployment URL. Then generate a production deploy key with full permissions:

    • deployment:deploy— push functions & schema
    • env:view — read existing backend env vars
    • env:write — let the build provision auth env vars for you

    The env:write scope is what makes the auth bootstrap (step 4) zero-touch. A read-only key will make the build fail trying to write JWT keys.

  2. Set the two env vars in Vercel

    In your Vercel project → Settings → Environment Variables, add both for the Production environment:

    NEXT_PUBLIC_CONVEX_URL=https://<your-deployment>.convex.cloud
    CONVEX_DEPLOY_KEY=<your-full-permission-deploy-key>

    NEXT_PUBLIC_CONVEX_URL is what the browser uses to talk to Convex; CONVEX_DEPLOY_KEY is what the build uses to deploy the backend before next build runs.

  3. Pick how the first admin gets created

    A fresh Convex backend has an empty users table, so it needs exactly one first admin. Choose either path:

    A. Zero-touch (set env vars)

    Set these in your Convex env (dashboard → Settings → Environment Variables). The first admin is created automatically on deploy:

    ADMIN_EMAIL=you@example.com
    ADMIN_PASSWORD=<a-strong-password>

    B. Claim ownership in-app

    Skip the env vars. After deploy, visit /dashboard/admin and click Claim ownership — the first account to sign up becomes the admin.

  4. Push — the build provisions auth and deploys

    Push to your default branch (or hit Deploy in Vercel). The build command runs three steps in order, all idempotent:

    setup-auth   # provisions JWT_PRIVATE_KEY, JWKS, SITE_URL in Convex
    convex deploy   # pushes schema + functions to your backend
    next build      # builds the Next.js app with NEXT_PUBLIC_CONVEX_URL

    setup-auth only writes env vars that are missing, so re-running it never rotates keys or breaks existing sessions.

  5. Optional — load sample data

    Want content to look at before adding your own? Sign in as the admin and click Load sample data in the admin panel, or run the seed from your machine:

    npx convex run seed:run

    The seed is idempotent too — re-running it tops up missing rows rather than duplicating everything.

Why does my fresh clone look read-only?

Because it is — on purpose. A fresh Convex backend ships with an empty users table. Until you become the first admin — by setting ADMIN_EMAIL / ADMIN_PASSWORD (step 3A) or by signing up and claiming ownership (step 3B) — there is no authenticated user, so every edit and mutation is blocked.

That locked-down state is expected, not a bug. As soon as the first admin exists, the dashboard becomes fully writable. Nothing to delete, nothing to recreate — just finish step 3.