Supabase Plugin - Integrate Supabase into your Bubble app

Hi @ZeroqodeSupport - thank you for the response.

A quick follow-up question, I have some workflows like this with Supabase error notification with condition of it being run only when it’s not live version. Do you know i this type of things is also eating into the load time?

Hi @steven.h.liu.1,

Good question! The short answer is: no, that specific workflow shouldn’t add to your load time in any meaningful way.

That workflow is an Element Event triggered by a Supabase fetch error — it only runs if and when the fetch fails. It doesn’t run proactively on page load. And since the condition is “Only when isn’t live version,” it won’t even fire in production at all.

That said, there’s a related point worth flagging. In your HAR trace, the user_profile query fires with an empty user ID filter (user_id=in.()), meaning it executes before the SupabaseAuth element has resolved a user. That query is likely returning an error or empty result — which would trigger your error workflow in dev mode. The workflow itself isn’t the bottleneck, but the query firing too early (before auth is ready) is a wasted round-trip. Adding a condition so that fetch only runs when the SupabaseAuth user ID is not empty would eliminate both the unnecessary request and the error.

One more thing that IS hurting your load time: duplicate queries. In the HAR I can see tag?select=* firing twice with identical parameters on the same page load. Each duplicate means an extra CORS preflight (OPTIONS) + the actual GET request — that’s 2 extra network round-trips for data you already have. Check if you have multiple SupabaseDatabase elements or workflows querying the same table, and consolidate them into a single fetch. Same goes for user_profile, which fires in two different forms. Every duplicate query adds ~200-500ms depending on network conditions.

Hope that helps!

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
Banner_Last3

Hi @ZeroqodeSupport - thank you for the responses. I’m going through streamlining my app right now, and it’s definitely noticeably faster.

I do have another question that I hope you can help me with. I have a Supabase uploader in the reusable element; the path I set for it is [page’s user_id; this is a custom state]/event/.

However, when the file is actually uploaded and saved, it would skip out on the user_id and directly go to /event/, so a completely different file path (see video below). The exact same setup works when the uploader is stored in a page vs. reusable. The reusable element is a group.

I recorded a video to showcase this (Google drive LINK)

Hello @steven.h.liu.1 ,

This is a situation that we see very often with the reusable element, since in Bubble the reusable seems to not have direct access to page-level data right away.
It is a simple timing/sequencing issue.

When the uploader tries to resolve page's user_id (your custom state), it returns empty/null inside the reusable element — so the path collapses from {user_id}/event/ to just /event/ .

You can try the following approach: pass the value into the reusable element

  1. On the reusable element, define a custom state (e.g., user_id, type: text) or use the reusable’s Content Type to pass data in.
  2. On the page where you place the reusable, set the reusable’s user_id custom state (or data source) to page's user_id.
  3. Inside the reusable, update the uploader path to reference the reusable’s own custom state instead of page's user_id:
This ReusableElement's user_id/event/

Let me know if this resolves the issue for you.

By the way, we’re glad to hear that streamlining the app helped with the performance. Dont worry if you’re not hitting expected timings right away - sometimes it’s a matter of trusting the process.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
Banner_Last3

Hi @ZeroqodeSupport - I have a Google auth situation. I recently created an independent separate sign-in page. However, when I went through the sign-in and got redirected to url, the session wouldn’t stay signed in

___________________

EDIT1. I also sent you a video via DM (due to personal email addresses) to explain the situation more clearly.

EDIT2. It seems if I redirect back to my “sign-in” page first vs. home_page, the auth would happen and continue to persist across the pages, but if I redirect to home_page, it wouldn’t recognize the authentication session

Hello @steven.h.liu.1,

We’ve received your message and are reviewing the video along with the screenshots.
Since the discussion may involve sensitive data, we’ll make sure to respond via DM.

Please bear with us while we review the setup.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
Banner_Last3

Hi @ZeroqodeSupport - quick questions.

  1. I have a jsonb field in my database. How do I set it in Bubble to read it correctly in the frontend?
  2. When I use SQL query function to query something into the Bubble frontend. How do I display the JSON without saving it into the bubble database?

Hi Steven,

Thanks for reaching out! Here are the answers to your questions:

Regarding Question 1: This seems to lean more toward a general Bubble data formatting question rather than being specific to the Supabase plugin’s functionality, but I am happy to help point you in the right direction.

Could you clarify what you mean by reading it correctly? Are you trying to display the extracted ‘content’ of the JSON without the raw formatting?

For example, instead of displaying the raw data like this:

[
  {
    \"message\": \"message 1\"
  },
  {
    \"message\": \"message 2\"
  },
  {
    \"message\": \"message 3\"
  }
]

…are you trying to parse it to return just a clean list of texts: “message 1”, “message 2”, “message 3”? Let me know what your exact end goal is for the frontend, and I can suggest the best Bubble approach.

Regarding Question 2: You can definitely do this! You can find the relevant documentation for this action here: Server Side Actions - Run SQL Query.

The ‘Run SQL Query’ is a workflow action, which means it executes and returns a payload immediately within that workflow. To display the JSON on your frontend without saving it to the Bubble database, you simply need to grab the result of that action in a subsequent step.

For example:

Step 1: Run SQL Query.
Step 2: Reference Result of step 1 (Run SQL Query’s Result (JSON)) and pass that data to your UI.
You can pass this data by using the “Display data in group” action to send it directly to a visual element, or by using “Set state” to save the JSON to a Custom State on the page. Your frontend elements can then just read dynamically from that group or custom state.

I hope this helps! Let me know if you have any other questions.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
Banner_Last3

hi @ZeroqodeSupport - appreciate the help.

Re: Q1. I have a “jsonb” column in the Supabase table with clean formatting (see below for sample json payload). I understand Bubble always require us to specify the json structure in order to read it, so I assume as long as I specify the structure as such in API connector, Bubble will be able to read the json?

{
  "account_id": 1,
  "start_date": 20240401,
  "duration": 30,
  "metric_type": "engagement",
  "platform_id": 1,
  "audience_demographics": {
    "age": {
      "18-24": 28,
      "25-34": 311,
      "35-44": 105,
      "45-54": 12,
      "55-64": 8,
      "65+": 3
    },
    "gender": {
      "F": 388,
      "M": 101,
      "Other": 73
    }
  }
}

Q2. Do you mind clarifying a bit more? I am a bit lost at this step of the setup (backend workflow- see pic):

Also, if I end up getting the json payload via the SQL query (similar to above), how would i parse the json into something Bubble can read? (i assume it’s just specifying the top section of the “Run SQL query”- see last pic)

________________________________________

EDIT1. I used Run SQL query on the backend because i don’t want to expose my access key in the frontend.

EDIT2. Could I use RPC to achieve what I want to achieve vs. SQL query management?

@ZeroqodeSupport- happy Fri. want to do a quick follow-up on the above

Hello @steven.h.liu.1 ,

Thank you for your patience.

You’re right, apologies for the confusion — “Run SQL Query” is indeed a server-side action in the Supabase Pro Kit plugin.

Q1: Reading JSONB in Bubble
Yes — as long as you define the expected JSON structure in the plugin’s action configuration, Bubble will be able to parse and read the JSONB response.

Q2: Parsing JSON from “Run SQL Query”
Yes, you define the expected return structure in the top section of the “Run SQL Query” action. The plugin will use that to parse the JSONB into fields Bubble can read. Refer to the server-side actions docs for the exact field mapping setup.

EDIT2: RPC vs. SQL Query
Yes, you can use the plugin’s RPC action instead. It’s the better option — your query logic stays in Supabase as a Postgres function, making it easier to maintain and more secure. The plugin supports RPC natively as a server-side action.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
BannerLast3

Hi @ZeroqodeSupport- thank you for all the help.

I have a quick question re: link preview and Supabase load. It seems when bots are crawling the html, Supabase fetch wouldn’t be triggered. Do you know how i would be able to feed the Supabase data info to the link preview?

More detail HERE.

Hi Steven,

Apologies for the delayed response.

Yes — this is expected behavior. Most link-preview bots/social crawlers only read the initial HTML returned by the Bubble page. They usually don’t wait for client-side workflows, page-load actions, or plugin calls to finish. Since the Supabase Pro Kit fetch/RPC/database actions run after the Bubble page loads in the browser, the crawler won’t trigger those Supabase calls, so that data won’t be available to the link preview automatically.

For link previews, the meta tags need to be available in the page HTML at crawl time. So the practical options are:

Store the preview fields in Bubble as well
For example: title, description, image URL, slug, etc. Then use Bubble’s SEO / metatag settings to populate the link-preview tags from Bubble data directly.

Use a server-side/API workflow as an intermediate layer
You could fetch the required Supabase data server-side first, save/cache the preview values somewhere Bubble can access for SEO, and then use those saved values for the page’s metatags.

Use a dedicated dynamic preview route/page
Create a lightweight Bubble page specifically for sharing, where the required preview data is already available from Bubble’s database or another server-side-accessible source before the crawler reads the HTML.

Use Supabase Edge Functions / RPC only as part of a server-side preparation flow
Supabase Pro Kit supports RPC and Edge Function workflows, but if they’re triggered only on page load in the client, crawlers still won’t wait for them. So the key point is not just “fetching from Supabase,” but making sure the final preview values are already present in the rendered HTML/meta tags when the bot requests the URL.

So in short: I wouldn’t rely on the Supabase fetch action to feed link previews directly. The safest approach is to sync/cache the needed preview fields into Bubble or another server-rendered endpoint, then reference those values in Bubble’s SEO/meta tag settings.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
BannerLast3

Hi @ZeroqodeSupport - no worries about the delay. Thank you for the response.

Quick question on cache supabase data onto bubble. How would I accomplish that? I am a bit unfamiliar with the setup on this front.

Hi Steven,

This is just a suggestion from our side, and more of a workaround than an official “one correct” architecture. It can probably be improved depending on your exact app setup, and hopefully other Bubble/Supabase users in the community can also suggest a cleaner approach.

The main challenge with link previews is that platforms like iMessage, Facebook, LinkedIn, Slack, etc. usually read the page’s metadata before the Bubble page has fully loaded dynamic data from Supabase. So even if the profile displays correctly for a normal user, the preview crawler may only see the generic Bubble page title/image/description.

One possible workaround is to cache only the public profile preview data from Supabase into Bubble.

For example, let’s say your Supabase profile table has:

profiles

- id
- slug
- display_name
- headline
- avatar_url
- updated_at

In Bubble, you could create a data type such as:

Cached Profile

With fields like:

supabase_id: text
slug: text
display_name: text
headline: text
avatar_url: text
supabase_updated_at: date

Then your Bubble profile page could have:

Type of content: Cached Profile
Copy
And your dynamic page metadata could use:

Title:
Current Page Cached Profile's display_name

Description:
Current Page Cached Profile's headline

Image:
Current Page Cached Profile's avatar_url

So the general idea would be:

Supabase = source of truth
Bubble Cached Profile = small public cache used for page metadata / link previews

When a user creates or updates their profile, you would update Supabase as usual, but also create/update the matching Cached Profile thing in Bubble.

Example workflow:

- User saves profile
- Update profile in Supabase
- Search Bubble for Cached Profile where supabase_id = Supabase profile id
- If found, update it
- If not found, create it

Then the profile URL should point to the Bubble cached profile record, for example:

/profile/steven-liu

or whatever URL structure you are using, so Bubble can resolve the current page’s Cached Profile and generate the correct metadata before the link preview crawler reads the page.

If profile data can also be changed outside Bubble, then instead of only syncing on profile save, you could run a scheduled backend workflow that fetches profiles updated after the last sync time from Supabase and updates the Bubble cache.

Again, this is only a suggested workaround. I would not recommend duplicating your whole Supabase database into Bubble. For this specific use case, you would only need to cache the public fields required for the preview, such as the profile name, short description/headline, slug, and image URL.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
BannerLast3

Got it- so not a literal cache but a data table within Bubble that stores the needed info.

Let me try to set it up and (possibly) circle back with any questions.

Thank you!

@ZeroqodeSupport - i started to set up the SEO profile by creating a Bubble database table.

However, i’m encountering a bit of an error. When I create an entry on bubble table by inputting supabase’s fetch results (see pic), the bubble table generates empty fields:

Workflow Setup:

Debug Mode:

Database Result:

Hello @steven.h.liu.1 ,

Since the debugger shows that both description and media are receiving values inside the workflow action, the Supabase fetch itself seems to be returning the data correctly.

In this case, the most likely cause is either Bubble privacy rules hiding the saved fields, or another workflow action modifying the same SEO thing after the values are assigned.

As a quick test, please temporarily disable the privacy rules for the SEO data type, or make the relevant fields publicly visible, then run the workflow again and check whether the values appear.

If the fields are still empty, please run the workflow with debug_mode=true and use Run next step by step. This will help confirm whether the values are saved during the “Create a new SEO” step and then possibly cleared by a later action.

Best regards,
Zeroqode Support Team
Browse all Zeroqode Plugins for Bubble
BannerLast3