# \[Supabase\] Switch between Production and Staging in one click

**URL:** <https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972>\
**Category:** Tutorials\
**Tags:** supabase\
**Created:** [June 5, 2024, 8:03pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972 "2024-06-05T20:03:01Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Broberto](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/broberto/32/5918_2.png) [@Broberto](https://community.weweb.io/u/Broberto)\
**Post date:** [June 5, 2024, 8:03pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/1 "2024-06-05T20:03:01Z")

</div>

## Preface

Since I kind of opened this discussion a few days ago, in this thread [[Chrome Extension] Supabase Live and Staging](https://community.weweb.io/t/chrome-extension-supabase-live-and-staging/8849) I actually found a really neat way of doing this, at least while WeWeb rolls out their own solution.

This solution also doesn’t account for the part where WeWeb uses the Private - Secret keys to fetch things like fetching the users etc. What does this work on?

- Fetching the tables within your collections creating process a.k.a it can introspect your DB’s schema
- Changing the auth endpoint, so you can authenticate with the users from your other instance, e.g. localhost
- Mocking / redirecting the request towards our localhost, or our any other Supabase instance

## Disclaimer

I don’t encourage you guys to paste any sensitive API keys anywhere, especially the Private API keys in this case of Supabase. In this “tutorial” I’m gonna be using only the Public API key, so that we can set up the Supabase properly.

## Prerequisites

1. First of all, you’ll need the [Requestly - Extension for Chrome](https://requestly.com/). The team behind this extension is amazing, big kudos to them, they actually fixed an issue so I could make this work with Supabase in a matter of days. _- The free plan should be enough, as our setup is very minimal, but I strongly encourage you support them, as they made this possible._
2. You’ll need your second instance or a self-hosted instance as shown by @flo in a tutorial, more resources about the self-hosting at the end - in the `References` section
3. You’ll need a WeWeb App set up with the Supabase plugin, on your “production” instance

## How it works

The process itself is very simple, we’re gonna be intercepting and modifying the requests that WeWeb does to Supabase, for this we’ll need to gather a few things first. For clarity I will be using `Staging` and `Production` to identify our two Supabase Instances.

We’ll need to get the following things from our Supabase Dashboard:

1. The `Production` instance’s URL, this also can be found in WeWeb plugin’s setup, or you can get this via the Network tab in your browser.
2. From the `Staging` instance, we’re gonna be getting the Public URL and Public API key. I repeat, in the ideal case please, use the Public key.

After this we head to the Requestly Extension and set up the following rules via the drop-down:

 ![Screenshot 2024-06-05 at 21.50.32](https://us1.discourse-cdn.com/flex016/uploads/weweb/original/2X/5/5ca322168ecae935a0692d252c4c273219456b58.jpeg)

### We modify the Public URL first

With this rule we’ll be intercepting the WeWeb’s calls with your Production’s URL and we’ll be replacing the URL part to match our Staging URL. For this we apply the setup shown in the screenshot while using the Requestly’s `Replace String` rule.

 ![Screenshot 2024-06-05 at 21.49.24](https://us1.discourse-cdn.com/flex016/uploads/weweb/original/2X/b/b3f04b50e1d04898724c9b6b984f9b11f9b01671.png)

### We alter the `<apikey>` headers to match our Public URL

With this rule we’ll be intercepting the WeWeb’s calls with your fresh new Staging URL that we replaced and we’ll be replacing request’s Headers with our Staging’s URL in order to match the two. For this we’ll use the Requestly’s `Modify headers` rule.

 ![Screenshot 2024-06-05 at 21.47.44](https://us1.discourse-cdn.com/flex016/uploads/weweb/original/2X/7/7c7329134ee303a14fec6a08aff40f081199215d.png)

And that’s it! Simple as that, you now can refresh your page and switch on and off the rules at your pleasing. This will allow you to do many things, such as testing your Staging changes within the Editor etc.

If you go beyond “trying out and testing the modified tables/endpoints” I highly suggest creating a folder within WeWeb to separate the “Staging” collections/workflows/whatever you do from your Production stuff, to avoid mess.

### Big thanks to the Requestly guys

I can’t praise these new found friends more, they worked on some issues that their extension had with me in a super short timeline and eventually worked it out supafast, making this tutorial possible. I definitely strongly suggest supporting them.

### Closing words

I hope this helps at least some people to make their workflow a little more pleasurable while we are waiting for a proper implementation from WeWeb’s side. If anyone struggles, or needs some help, and this goes for anything, not just Supabase, feel free to message me, drop a comment here, or eventually check out the [little link I have in my bio,](https://cal.com/broberto/no-code) where I do 1:1 sessions with aspiring no-coders 🙂

## References

> [@Supabase Test vs Live Database (if possible)](https://community.weweb.io/t/supabase-test-vs-live-database-if-possible/4758/6):
>
> yes! Here’s [a video @flo recorded on the topic](https://www.loom.com/share/268713829b8c4f98be138cddc48010bb). I still need some time to go through it and record a “tighter” version but hopefully it can get you started slight_smile

> **[Managing Environments | Supabase Docs](https://supabase.com/docs/guides/deployment/managing-environments)**
>
> Manage multiple environments using Database Migrations and GitHub Actions.

---

<div class="post-metadata">

**Author:** ![Joyce](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/joyce/32/13232_2.png) [@Joyce](https://community.weweb.io/u/Joyce)\
**Post date:** [June 6, 2024, 10:33am UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/2 "2024-06-06T10:33:31Z")

</div>

Very cool! Thanks so much for taking the time to put this together @Broberto, appreciate it! 🙂

---

<div class="post-metadata">

**Author:** ![abhishek-rq](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@abhishek-rq](https://community.weweb.io/u/abhishek-rq)\
**Post date:** [June 10, 2024, 7:38am UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/3 "2024-06-10T07:38:32Z")

</div>

Just 1 tiny tip, put both the rules in a collection to manage active/inactive status with 1 click. Every click matters 🙂 .

---

<div class="post-metadata">

**Author:** ![Broberto](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/broberto/32/5918_2.png) [@Broberto](https://community.weweb.io/u/Broberto)\
**Post date:** [June 10, 2024, 8:02am UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/4 "2024-06-10T08:02:49Z")

</div>

Hey! Good tip 🙂 I didn’t look into this that deeper, as it seems like they are “depending” on each other. So if I disable the main one (e.g the Public URL one) the depending one (apikey) never fires. But definitely, your tip is more bulletproof 💪 Thanks!

---

<div class="post-metadata">

**Author:** ![abhishek-rq](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@abhishek-rq](https://community.weweb.io/u/abhishek-rq)\
**Post date:** [June 10, 2024, 9:40am UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/5 "2024-06-10T09:40:09Z")

</div>

You are right, the Replace rule is the main rule. I liked how you described using collections as “bulletproof” — it’s a great metaphor! 😊

One edge case I was considering is that the header rule can sometimes interfere with staging calls, but of course, this highly depends on the particular use case and setup. Just a general observation. 👍

---

<div class="post-metadata">

**Author:** ![Larry](https://avatars.discourse-cdn.com/v4/letter/l/47e85d/32.png) [@Larry](https://community.weweb.io/u/Larry)\
**Post date:** [June 28, 2024, 4:07pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/6 "2024-06-28T16:07:46Z")

</div>

Many thanks for this! This works perfectly for me in the editor, but not in staging. Any ideas what might cause that? I can authenticate successfully but my fetch requests do not return any data. I can fetch data without issue when I duplicate the requests in Postman.

---

<div class="post-metadata">

**Author:** ![Broberto](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/broberto/32/5918_2.png) [@Broberto](https://community.weweb.io/u/Broberto)\
**Post date:** [June 28, 2024, 4:24pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/7 "2024-06-28T16:24:40Z")

</div>

Hello, I’m glad it works. I’d need to see the network tab, and get to know your staging/prod to indentify them, and eventually understand the issue though. My best guess is that you could find answers in the Console and Network tabs.

---

<div class="post-metadata">

**Author:** ![Matt](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/matt/32/13947_2.png) [@Matt](https://community.weweb.io/u/Matt)\
**Post date:** [May 28, 2025, 8:36pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/8 "2025-05-28T20:36:45Z")

</div>

Just bumped into the topic, after having implemented a solution for a mutli-environment myself.

The idea of a plugin is not really what I like most, what i’ve done is that I’ve **only used variables** and **formulas** so far to get my calls to the right supabase database, using the _ **environment** _ variable.

I’d be interested to see how it would work by implmenting the SDK ourselves

---

<div class="post-metadata">

**Author:** ![Matt](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/matt/32/13947_2.png) [@Matt](https://community.weweb.io/u/Matt)\
**Post date:** [June 25, 2025, 1:46pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/9 "2025-06-25T13:46:24Z")

</div>

@Broberto Question : how do you manage to make those staging and prod database **stay in sync ?**

---

<div class="post-metadata">

**Author:** ![Broberto](https://sea2.discourse-cdn.com/flex016/user_avatar/community.weweb.io/broberto/32/5918_2.png) [@Broberto](https://community.weweb.io/u/Broberto)\
**Post date:** [June 25, 2025, 2:21pm UTC](https://community.weweb.io/t/supabase-switch-between-production-and-staging-in-one-click/8972/10 "2025-06-25T14:21:55Z")

</div>

Usually I no longer touch prod when I deploy the product, I instead push migrations from the local enviroment. This way I never work on prod, but just update it to match work done on local and avoid incidents.
