Skip to content
Webflow+Supabase
Stack Integration

Webflow + Supabase Integration

Webflow handles your frontend and CMS. Supabase handles custom backend logic, user auth, and database queries Webflow's native tools can't reach.

Use Cases
  1. User auth on a Webflow site via Supabase Auth
  2. Custom member areas with Supabase-gated content
  3. Form submissions stored directly to Supabase Postgres
  4. Dynamic content from Supabase rendered via custom JS
Implementation

Use Webflow's custom code embed to initialize the Supabase JS client. Add the SUPABASE_ANON_KEY — the anon key is safe to expose client-side when RLS is configured correctly. Server-side logic (admin operations) always goes through a separate serverless function, never in Webflow's custom code.

In detail

How the pieces connect

Webflow renders the static HTML, CSS, and CMS content. Supabase runs everything that needs a real database or trusted server logic. There is no native plugin between them — you load the @supabase/supabase-js client inside a Webflow custom code embed and call it from the browser.

The split is clean: Webflow owns markup and styling, Supabase owns auth, Postgres, Storage, and Edge Functions. A typical flow is supabase.auth.signInWithPassword() on a Webflow login form, then a supabase.from('table').select() query whose results you inject into Webflow DOM nodes via plain JavaScript. The session lives in localStorage by default, so it survives navigation across Webflow pages without a backend session store. Anything that must stay secret — service_role keys, admin writes — runs in an Edge Function, never in the embed.

Production gotchas

The anon key is public by design, so Row Level Security is the only thing protecting your data. With no RLS policies, SUPABASE_ANON_KEY lets anyone read and write every table. Enable RLS on every table, then write select/insert/update policies keyed on auth.uid().

Webflow's editor and live site are different origins than your local preview, so add each one to Supabase's allowed redirect URLs under Auth settings, or email confirmations and OAuth callbacks bounce. Webflow also strips or reorders custom code on republish — keep the Supabase init in a single Footer Code or page-level embed, not scattered across elements.

Watch the load order: the embed runs before Webflow's interactions finish, so guard DOM lookups (DOMContentLoaded) before injecting query results, or you write into nodes that do not exist yet.

Security considerations

Treat the browser as untrusted. Validate and authorize on the database with RLS policies, not in the JavaScript embed, since anyone can open DevTools and replay your calls with their own values. Use auth.uid() inside policies so a row is only readable or writable by its owner.

Never paste the service_role key into Webflow custom code — it bypasses RLS entirely. Privileged work (deleting other users' rows, sending email, charging a card) belongs in a Supabase Edge Function that checks the caller's JWT before acting. For form submissions, prefer an insert policy scoped to the expected shape, or proxy through an Edge Function that does server-side validation. If you accept file uploads, set Storage bucket policies explicitly — a public bucket is readable by anyone with the URL.

When this combo fits — and when it doesn't

It fits when you want Webflow's visual building and CMS for marketing pages but need real auth, a relational database, or gated member content that Webflow's native Memberships can't model. Storing structured form data in Postgres, building a logged-in dashboard area, or querying dynamic data client-side are all good matches.

It fits poorly when the logic is heavy or latency-sensitive. Rendering large Supabase result sets through client JS means no SSR, weaker SEO for that content, and a flash of empty state on load. If most of the app is dynamic and authenticated, a real framework (Next.js on Supabase) is the better base and Webflow becomes the wrong layer. Use this pairing for content-led sites with a backend bolted on — not for an app wearing a Webflow shell.

Other integration guidesView all →
Related

Need this built?