Back to blog
How to Add a Supabase Backend to an AI-Generated React App — CloudCode blog

How to Add a Supabase Backend to an AI-Generated React App

8 min readTutorial

Add Postgres, auth, and row-level security to an AI-built React app: agent-generated migrations you review, email sign-in, real queries, and a security checklist before you deploy.

Why Supabase Is the Default Backend for AI-Built Apps

AI app builders are very good at frontends. The moment your app needs to remember something — users, orders, settings — you need a backend, and that's where many AI-generated projects stall. Supabase has become the default answer for React apps because it gives you a hosted Postgres database, authentication, file storage, and edge functions behind a single JavaScript client, with row-level security (RLS) to enforce who can read and write what.

This tutorial shows how to add a Supabase backend to an AI-generated React app in CloudCode, a browser-based AI app builder and cloud IDE where the Claude Code Agent writes and fixes your code next to a live preview. You'll create the database schema with agent-generated migrations, add email sign-in, protect data with RLS, and verify everything in the preview before deploying. The same approach works for an app you built in CloudCode or one you imported from another tool.

Before You Start

You need two things:

  • A CloudCode project with a React frontend. If you don't have one, follow [How to build a SaaS dashboard with AI and deploy it to Vercel](/blog/build-saas-dashboard-ai-deploy-vercel) or start from the [dashboard template](/templates/dashboard).
  • A free Supabase account. Your database lives in your own Supabase project, which means you own the data and can manage it from the Supabase dashboard whether or not you keep using CloudCode.

Step 1 — Create a Supabase Project

In the Supabase dashboard, create a new project, choose a region close to your users, and set a strong database password. When it finishes provisioning, open the project's API settings and copy two values:

  • Project URL — looks like 'https://abcd1234.supabase.co'
  • anon (public) key — a long JWT intended for browser use

You'll also see a service_role key. Do not put it anywhere in your frontend code. It bypasses row-level security and belongs only in server-side code such as edge functions.

Step 2 — Wire Up the Supabase Client

Open the agent chat and ask:

"Install @supabase/supabase-js. Create src/lib/supabaseConfig.ts exporting SUPABASE_URL and SUPABASE_ANON_KEY, and src/lib/supabase.ts that creates and exports a single Supabase client from them. I'll paste the values."

The agent adds the package to 'package.json' (the preview fetches it from there) and writes both files. Paste your Project URL and anon key into the config file.

Why a config file rather than 'import.meta.env'? Neither CloudCode's dev preview nor its one-click deploys inject environment variables into your app. The anon key is designed to be public — it's what every Supabase web app ships to the browser, and RLS is what protects your data — so a config module is safe and works the same in preview and in production.

Also add both values in CloudCode's environment variable manager under the Development, Staging, and Production tabs. That keeps a record of what the app expects, lets the agent's environment check confirm nothing is missing, and means the variable names are included in the '.env.example' CloudCode generates when you push to GitHub. If you later move to a git-driven build pipeline, switching the config module to read 'import.meta.env' is a two-line change.

Step 3 — Design the Schema With the Agent

Describe the data your app needs in plain language. For a simple SaaS app:

"Design a Supabase schema for this app. I need a profiles table linked to auth.users, a projects table owned by a user, and a tasks table that belongs to a project. Enable row-level security on every table so users can only read and write their own rows. Generate it as a migration."

The agent writes the SQL and saves it as a migration file under 'supabase/migrations', with a timestamped name like '20261102120000_initial_schema.sql' and a header recording what it does and when it was generated. Crucially, it creates the migration but does not run it. Schema changes are the one place you want a human in the loop.

Open the file in the editor and review it. Things to check:

  • Every table has RLS enabled.
  • Policies use 'auth.uid()' to match the row's owner column.
  • Foreign keys reference the right tables and have sensible on-delete behaviour.
  • There's a trigger or a clear plan for creating a profile row when a user signs up.

When you're happy, apply it: paste the SQL into the Supabase dashboard's SQL editor and run it, or push the project to GitHub and apply the migrations with the Supabase CLI from a machine where it's installed. Keeping migrations as files in the repo means your schema history travels with your code.

Step 4 — Add Authentication

Next, ask the agent to add sign-in:

"Add email and password authentication with Supabase. Create sign-up and sign-in pages, an auth context that listens to onAuthStateChange, a sign-out button in the header, and a ProtectedRoute component that redirects signed-out users to the sign-in page. Protect every page except sign-in and sign-up."

The agent will touch several files at once — routes, a context provider, the two pages, the header — and wire them together. In the Supabase dashboard, check the authentication settings: decide whether new users must confirm their email, and add your preview and deployed URLs to the allowed redirect URLs so confirmation links land in the right place.

Step 5 — Replace Mock Data With Real Queries

If your app was built with mock data, now's the time to swap it out. If the agent originally put that data behind its own module, this is a contained change:

"Replace the mock data in src/data/mockData.ts with Supabase queries. Fetch the signed-in user's projects and tasks, add create, update, and delete functions, and handle loading and error states in the components."

Mismatched types between the database and the UI are the most common source of bugs at this stage, so ask the agent to write TypeScript interfaces that match your migration and use them in the queries, so they're typed end to end. Then check the preview for errors — and once you push to GitHub, let a real type-check in CI catch anything that slipped through.

Step 6 — Test in the Live Preview

Sign up with a test account in the preview and create a few records. Then open the drawers under the preview:

  • The console drawer shows client errors. The agent can read console errors from the preview too, so "check the preview console and fix any Supabase errors" is a useful prompt.
  • The network drawer in Live mode (after a deploy) records each fetch request to your Supabase project with its method, status code and duration. A 401 usually means the user isn't signed in; an empty result with a 200 is the classic sign of an RLS policy that's too strict. In the dev preview, use your browser's DevTools for the same view.

Then test the security model, not just the happy path. Sign in as a second user and confirm you can't see the first user's data. If you can, a policy is missing — ask the agent to fix it with a new migration rather than editing the old one.

Step 7 — Storage and Edge Functions (Optional)

Two more Supabase features come up quickly in real apps.

File uploads. Create a storage bucket in the Supabase dashboard and ask the agent to add an upload component that stores files under a path that includes the user's id, with storage policies that restrict access to the owner.

Server-side logic. Anything that needs a secret — calling a payment provider, sending email, using the service_role key — belongs in a Supabase edge function, not in the browser. The agent can write the function under 'supabase/functions/your-function/index.ts' and the frontend call to invoke it; you deploy the function with the Supabase CLI and keep its secrets in Supabase's own secret store.

Step 8 — Deploy

With the backend wired up, deploy as usual from CloudCode's Deploy panel: Staging first, then Production. Add each deployed URL to Supabase's allowed redirect URLs so auth emails work on the live site. As your app grows, consider a separate Supabase project for staging so test data never mixes with production.

Security Checklist

Before you share the app, run through this list:

  • RLS is enabled on every table, and you've tested it with two different users.
  • The service_role key appears nowhere in your frontend code. Search for 'service_role' with the file explorer's content search to be sure.
  • Auth redirect URLs include only your own domains.
  • Storage buckets are private unless they genuinely need to be public.
  • Every schema change is a reviewed migration file in 'supabase/migrations'.

Wrapping Up

Adding a backend to an AI-generated React app doesn't have to mean leaving the AI workflow. In CloudCode, the agent adds the client, writes the auth flow and queries, and generates migrations — while you stay in control of the parts that matter: reviewing schema changes and testing your security rules. Your data lives in your own Supabase project, and your code lives in your own repo.

Start building in CloudCode with free credits and no card required. Coming from another builder? See how CloudCode compares to Lovable and Bolt.