Merge branch 'master' of github.com:supabase/supabase into chore/reference_v6

This commit is contained in:
Copple committed 2022-08-12 12:17:10 +02:00
commit f91d63d5c8
82 files changed
+1640 -1390

No files matched your search

@@ -2,8 +2,6 @@
title: Supabase vs Firebase
description: Supabase is an Open Source Firebase Alternative with a SQL based Database, Auth, and Cloud Functions
author: ant_wilson
image: partner-gallery/partner-showcase-thumb.png
thumb: partner-gallery/partner-showcase-thumb.png
tags:
- comparison
date: '2022-05-26'
@@ -44,7 +42,7 @@ Both Firebase and Supabase have invested heavily in client side libraries so you
## How are they different?
Firebase and Supabase differ in several ways. The main one being that Firebase is a document store, whereas Supabase is based on PostgreSQL - a relational, SQL-based database management system.
Firebase and Supabase differ in several ways. The main one being that Firebase is a document store, whereas Supabase is based on PostgreSQL - a relational, SQL-based database management system.
There are some other important differences.
@@ -2,8 +2,6 @@
title: Supabase vs Heroku Postgres
description: Supabase is an alternative to Heroku Postgres with Enterprise Grade Support available
author: ant_wilson
image: partner-gallery/partner-showcase-thumb.png
thumb: partner-gallery/partner-showcase-thumb.png
tags:
- comparison
date: '2022-05-26'
@@ -173,6 +173,13 @@ Data can also be viewed directly from the Supabase dashboard. To do this, go to
Note: In case you cannot see any of the data, you should hit the Refresh button.
## Conclusion
With Python, data loading into Supabase is easy. It just takes a few easy steps to get started with the Python SDK and Supabase. In the next part of this blog series, we will learn [how to visualize the data that we just loaded into Supabase using Metabase](blog/visualizing-supabase-data-using-metabase). Stay tuned!
With Python, data loading into Supabase is easy. It just takes a few easy steps to get started with the Python SDK and Supabase. In the next part of this blog series, we will learn [how to visualize the data that we just loaded into Supabase using Metabase](/blog/visualizing-supabase-data-using-metabase). Stay tuned!
If you have any questions please reach out via [Twitter](https://twitter.com/supabase) or join our [Discord](https://discord.supabase.com).
## More Python and Supabase resources
- [supabase-py](https://github.com/supabase-community/supabase-py)
- [Slack Consolidate: a slackbot built with Python and Supabase](blog/slack-consolidate-slackbot-to-consolidate-messages)
- [Supabase-py (Database) on Replit](https://replit.com/@Supabase/Supabase-py-Database?v=1)
@@ -16,7 +16,7 @@ Data helps organizations make better decisions. With a programming language like
With Metabase, a powerful visualization tool, you can quickly turn your data into easy-to-understand visuals like graphs, pie charts, flow diagrams, and much more. Then, using Metabase’s intuitive interface, you can cut through the data noise and focus on what’s essential for your business.
In the previous blog of this series**,** we explained [how to use Python to load data into Supabase](https://supabase.com/blog/loading-data-supabase-python). In this blog, we will create different kinds of charts out of the data stored in Supabase using Metabase.
In the previous blog of this series, we explained [how to use Python to load data into Supabase](https://supabase.com/blog/loading-data-supabase-python). In this blog, we will create different kinds of charts out of the data stored in Supabase using Metabase.
## Prerequisites
@@ -133,3 +133,8 @@ Data visualization empowers organizations to turn unused data into actionable in
With our [free tier Supabase account](https://app.supabase.com/), you can start a new project today and use Metabase to visualize your app data.
If you have any questions please reach out via [Twitter](https://twitter.com/supabase) or join our [Discord](https://discord.supabase.com).
## More Python and Supabase resources
- [supabase-py](https://github.com/supabase-community/supabase-py)
- [Slack Consolidate: a slackbot built with Python and Supabase](blog/slack-consolidate-slackbot-to-consolidate-messages)
- [Supabase-py (Database) on Replit](https://replit.com/@Supabase/Supabase-py-Database?v=1)
@@ -146,7 +146,7 @@ SupaSocialsAuth(
## Final thoughts
These updates are just the tip of the iceberg for 1.0. There are been many bug fixes and features constantly being added to the Supabase Flutter SDK. This could not have been possible with the help from the open source community. Here, I would also like to give a shout out to two other developers who have been a major part of the journey of this SDK: [Vinzent](https://twitter.com/Vinzent03_) and [Daniel Mossaband](https://github.com/DanMossa). They have been a huge part of the Supabase Flutter SDK - not just for the 1.0 release, but throughout the lifetime of the library.
These updates are just the tip of the iceberg for 1.0. There are been many bug fixes and features constantly being added to the Supabase Flutter SDK. This could not have been possible without the help from the open source community. Here, I would also like to give a shout out to two other developers who have been a major part of the journey of this SDK: [Vinzent](https://twitter.com/Vinzent03_) and [Daniel Mossaband](https://github.com/DanMossa). They have been a huge part of the Supabase Flutter SDK - not just for the 1.0 release, but throughout the lifetime of the library.
For those of you who want to try out the new SDK, you can get the developer preview version from [supabase-flutter](https://pub.dev/packages/supabase_flutter/versions/1.0.0-dev.1) pub.dev page or can simply copy and paste the following into your pubspec.yaml file.
```yaml
@@ -2,8 +2,8 @@
title: 'Slack Consolidate: a slackbot built with Python and Supabase'
description: A slackbot to consolidate messages from different channels using Supabase, Slack SDK and Python
author: rodrigo_mansueli
image: slackbot-consilidate/slackbot-thumb.jpg
thumb: slackbot-consilidate/slackbot-thumb.jpg
image: slackbot-consolidate/slackbot-thumb.jpg
thumb: slackbot-consolidate/slackbot-thumb.jpg
tags:
- slack
- python
@@ -35,19 +35,19 @@ Now, it is time to create the bot in Slack and get the API Keys (after granting
[https://api.slack.com/apps](https://api.slack.com/apps)
![Green arrow pointing to the ‘Create New App’ button.](/images/blog/slackbot-consilidate/00_create_new_app.png)
![Green arrow pointing to the ‘Create New App’ button.](/images/blog/slackbot-consolidate/00_create_new_app.png)
Green arrow pointing to the ‘Create New App’ button.
Then, select to create an app from a manifest (this will already set the required permissions) for the app:
![Green arrow pointing to the option ‘From an app manifest’ inside the “Create an app” menu.](/images/blog/slackbot-consilidate/01_create_an_slack_app.png)
![Green arrow pointing to the option ‘From an app manifest’ inside the “Create an app” menu.](/images/blog/slackbot-consolidate/01_create_an_slack_app.png)
Green arrow pointing to the option ‘From an app manifest’ inside the “Create an app” menu.
Select the Slack workspace to deploy:
![The picture shows a dropdown UI with Supabase selected as the workspace.](/images/blog/slackbot-consilidate/02_pick_workspace.png)
![The picture shows a dropdown UI with Supabase selected as the workspace.](/images/blog/slackbot-consolidate/02_pick_workspace.png)
The picture shows a dropdown UI with Supabase selected as the workspace.
@@ -88,13 +88,13 @@ token_rotation_enabled: false
Enter the manifest above when asked:
![The picture shows the place where you have to paste the manifest file included in the repo.](/images/blog/slackbot-consilidate/03_enter_manifest.png)
![The picture shows the place where you have to paste the manifest file included in the repo.](/images/blog/slackbot-consolidate/03_enter_manifest.png)
The picture shows the place where you have to paste the manifest file included in the repo.
Then, confirm to create the bot:
![You can see a summary screen to confirm the creation of the bot and the scopes assigned.](/images/blog/slackbot-consilidate/04_confirm_window.png)
![You can see a summary screen to confirm the creation of the bot and the scopes assigned.](/images/blog/slackbot-consolidate/04_confirm_window.png)
You can see a summary screen to confirm the creation of the bot and the scopes assigned.
@@ -102,7 +102,7 @@ You can see a summary screen to confirm the creation of the bot and the scopes a
Install the app on the workspace:
![The picture shows the button to Install the App to the Slack Workspace.](/images/blog/slackbot-consilidate/05_install_workspace.png)
![The picture shows the button to Install the App to the Slack Workspace.](/images/blog/slackbot-consolidate/05_install_workspace.png)
The picture shows the button to Install the App to the Slack Workspace.
@@ -112,7 +112,7 @@ The command to invite the bot is below:
`/invite @SlackConsolidate`
![The picture shows the command /invite @Slackbot in the channel #team-support.](/images/blog/slackbot-consilidate/06_invite_bot_to_channel.png)
![The picture shows the command /invite @Slackbot in the channel #team-support.](/images/blog/slackbot-consolidate/06_invite_bot_to_channel.png)
The picture shows the command /invite @Slackbot in the channel #team-support.
@@ -151,7 +151,7 @@ CREATE TABLE slack_watcher (
You may want to call [conversations.list](https://api.slack.com/methods/conversations.list) to dump all the channels and channel IDs into a CSV file, then use it to populate the table `slack_channels`. You can also manually get the data, but copying the links to messages in the channels:
![After right-clicking a message in Slack, you can see the option to select the link.](/images/blog/slackbot-consilidate/07_copy_msg_link.png)
![After right-clicking a message in Slack, you can see the option to select the link.](/images/blog/slackbot-consolidate/07_copy_msg_link.png)
After right-clicking a message in Slack, you can see the option to select the link.
@@ -175,13 +175,13 @@ The name of the channel is not needed. But it is recommended to set, it so you c
Using Supabase UI (easier):
![The green arrow points to insert row button inside Supabase.](/images/blog/slackbot-consilidate/08_insert_row.png)
![The green arrow points to insert row button inside Supabase.](/images/blog/slackbot-consolidate/08_insert_row.png)
The green arrow points to insert row button inside Supabase.
Then, enter the information as needed:
![The picture shows the UI in Supabase to insert a new row to the database table.](/images/blog/slackbot-consilidate/09_insert_row_b.png)
![The picture shows the UI in Supabase to insert a new row to the database table.](/images/blog/slackbot-consolidate/09_insert_row_b.png)
The picture shows the UI in Supabase to insert a new row to the database table.
@@ -217,7 +217,7 @@ You need to get the supabase URL and API keys from here:
[https://app.supabase.com/project/\_/settings/api](https://app.supabase.com/project/_/settings/api)
![The picture illustrates where to get the URL and the service key to setup the environment variables.](/images/blog/slackbot-consilidate/10_copy_supabase_apis.png)
![The picture illustrates where to get the URL and the service key to setup the environment variables.](/images/blog/slackbot-consolidate/10_copy_supabase_apis.png)
The picture illustrates where to get the URL and the service key to setup the environment variables.
@@ -225,7 +225,7 @@ Slack environment variables:
Then, copy the bot and person API Tokens for the bot:
![The picture has arrows pointing to the tokens that will be used as environment variables from Slack.](/images/blog/slackbot-consilidate/11_copy_slack_apis.png)
![The picture has arrows pointing to the tokens that will be used as environment variables from Slack.](/images/blog/slackbot-consolidate/11_copy_slack_apis.png)
The picture has arrows pointing to the tokens that will be used as environment variables from Slack.
@@ -405,7 +405,7 @@ if __name__ == '__main__':
Of course, we aren't doing proper Python example if we don't make a test notebook available:
[![Open in Colab](/images/blog/2022-august/colab-badge.svg)](https://colab.research.google.com/github/mansueli/SlackConsolidate/blob/main/SlackConsolidate_bot.ipynb)
[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mansueli/SlackConsolidate/blob/main/SlackConsolidate_bot.ipynb)
## Conclusion
@@ -0,0 +1,118 @@
---
title: 'Launch Week 5 Hackathon'
description: Build to win $1500 - Friday 12th to Monday 21st August 2022
author: ant_wilson
image: lw5-hackathon/thumbnail.jpg
thumb: lw5-hackathon/thumbnail.jpg
tags:
- launch-week
date: '2022-08-10'
toc_depth: 3
---
# The Supabase Open Source Hackathon
Now is the perfect time to start your new Open Source project!
[Launch Week](https://supabase.com/launch-week) is about to start and we're running a hackathon in parallel for the entire duration.
There's a $1500 GitHub sponsorship and [gold Supabase caps](https://store.supabase.com/products/gold-supacap) to be won!
[Supabase-js v2.0](https://github.com/supabase/supabase-js/releases) and [Flutter SDK v1.0](https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview) will both be announced during Launch Week, they are both available already and using them in your project will gain extra credit!
<iframe
className="video-with-border w-full"
width="640"
height="385"
src="https://www.youtube-nocookie.com/embed/rI3Ik7GyYEw"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
## Key Facts
- You have 10 days to build a new **Open Source** project using Supabase.
- Starting 8:00am PT Friday 12th August 2022.
- Build whatever you want - a project, app, tool, library, anything
- Enter as an individual, or as a team of up to 5 people
- Submission deadline is 11:59pm Sunday night PT 21st August 2022
- There are 5 prize categories.
- Best overall project will win $1500 in GitHub sponsorships!
- Most technically challenging, most fun, best flutter project, and most visually pleasing will all win a Gold Supabase Cap!
![Gold cap](/images/blog/lw5-hackathon/spool.jpg)
## Details
### Schedule
- The Hackathon begins at 8:00am PT Friday 12th August 2022
- Work on your project any time for the next 10 days
- Submission deadline (11:59pm PT Sunday 21st August 2022)
### Prizes
There are 5 chances to win, there will be prizes for:
- Best Overall Project ($1500 in GitHub Sponsorship & Gold Cap)
- Most Visually Pleasing (Gold Cap)
- Most Technically Impressive (Gold Cap)
- Most Fun/Interesting (Gold Cap)
- Best Flutter Project (Gold Cap)
- *new* Best Realtime Project (Gold Cap)
There will be a winner and a runner-up prize for each category. Every team member gets a cap.
![Gold cap](/images/blog/lw5-hackathon/cap.png)
### Submission
You should submit your project using [this form](https://www.madewithsupabase.com/submission).
### Judges
The Supabase Founders will be judging, we will be looking for:
- creativity/inventiveness
- functions correctly/smoothly
- visually pleasing
- technically impressive
- use of Supabase features
- deep usage of a single feature or
- broad usage are both ok
- FUN! 😃
### Rules
- Team size 1-5 (all team members on winning teams will receive a prize)
- You cannot be in multiple teams
- One submission per team
- All design elements, code, etc. for your project must be created **during** the event
- All entries must be Open Source (link to source code required in entry)
- Must use Supabase in some capacity
- Can be any language or framework
- You must submit before the deadline (no late entries)
### Community
The Supabase Team will be taking part in the Hackathon and you'll find us live building in our discord all week. Please join us by building in public:
- Text channel: hackathon
- Audio channel: hackathon
If you need help or advice when building, find other people to join your team, or if you just want to chill and watch people build, come and join us!
[Join our Discord](https://discord.supabase.com)
![Discord Hangout](/images/blog/hackathon/community.png)
### Launch Week
Don't forget to checkout the new feature's being announced as part of [Launch Week](/launch-week).
### Additional Info
- Any intellectual property developed during the hackathon will belong to the team that developed it. We expect that each team will have an agreement between themselves regarding the IP, but this is not required
- By making a submission you grant Supabase permission to use screenshots, code-snippets and/or links to your project or content of your README on our Twitter, blog, website, email updates, and in the Supabase discord server. Supabase does not make any claims over your IP.
- $1500 prize will be paid by making a GitHub sponsorship to the winning repo, $500/month for 3 months. The goal here is to create a sustainable project that will be continue to be maintained for the duration of the sponsorship period (and hopefully beyond :) )
+1 -1
View File
@@ -64,7 +64,7 @@ const LayoutComparison = ({ components, props, gfm, slug }: Props) => {
openGraph={{
title: props.blog.title,
description: props.blog.description,
url: `https://supabase.com/blog/${props.blog.slug}`,
url: `https://supabase.com/alternatives/${props.blog.slug}`,
type: 'article',
article: {
//
+2
View File
@@ -6,6 +6,7 @@ module.exports = withMDX({
trailingSlash: false,
images: {
dangerouslyAllowSVG: true,
domains: [
'avatars.githubusercontent.com',
'github.com',
@@ -16,6 +17,7 @@ module.exports = withMDX({
'obuldanrptloktxcffvn.supabase.co',
'avatars.githubusercontent.com',
'colab.research.google.com',
'api.producthunt.com',
],
},
async headers() {
+1 -1
View File
@@ -70,7 +70,7 @@ export async function getStaticProps({ params }: any) {
nextPost: currentIndex === allPosts.length ? null : nextPost ? nextPost : null,
relatedPosts,
blog: {
slug: `${params.year}/${params.month}/${params.day}/${params.slug}`,
slug: `${params.slug}`,
content: mdxSource,
...data,
toc: toc(content, { maxdepth: data.toc_depth ? data.toc_depth : 2 }),
+1 -4
View File
@@ -104,10 +104,7 @@ function Blog(props: any) {
<div className="col-span-12 lg:col-span-12">
<Tabs scrollable size="medium" onChange={setCategory} defaultActiveId={'all'}>
{props.categories.map((categoryId: string) => (
<Tabs.Panel id={categoryId} key={categoryId} label={categoryId}>
{/* <p>{categoryId}</p> */}
<></>
</Tabs.Panel>
<Tabs.Panel id={categoryId} key={categoryId} label={categoryId} />
))}
</Tabs>
</div>
+3 -1
View File
@@ -100,7 +100,7 @@ export async function getStaticProps({ params }: any) {
nextPost: currentIndex === allPosts.length ? null : nextPost ? nextPost : null,
relatedPosts,
blog: {
slug: `${params.year}/${params.month}/${params.day}/${params.slug}`,
slug: `${params.slug}`,
content: mdxSource,
...data,
toc: toc(content, { maxdepth: data.toc_depth ? data.toc_depth : 2 }),
@@ -181,6 +181,7 @@ function BlogPostPage(props: any) {
description: props.blog.description,
url: `https://supabase.com/blog/${props.blog.slug}`,
type: 'article',
article: {
//
// to do: add expiration and modified dates
@@ -199,6 +200,7 @@ function BlogPostPage(props: any) {
url: `https://supabase.com${basePath}/images/blog/${
props.blog.image ? props.blog.image : props.blog.thumb
}`,
alt: `${props.blog.title} thumbnail`,
},
],
}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

+115 -109
View File
@@ -5,13 +5,19 @@
<link>https://supabase.com</link>
<description>Latest news from Supabase</description>
<language>en</language>
<lastBuildDate>Mon, 08 Aug 2022 03:03:00</lastBuildDate>
<lastBuildDate>Tue, 09 Aug 2022 06:06:00</lastBuildDate>
<atom:link href="https://supabase.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
<item>
<item>
<guid>https://supabase.com/blog/launch-week-5-hackathon</guid>
<title>Launch Week 5 Hackathon</title>
<link>https://supabase.com/blog/launch-week-5-hackathon</link>
<description>Build to win $1500 - Friday 12th to Monday 21st August 2022</description>
<pubDate>Tue, 09 Aug 2022 06:06:00</pubDate>
<item>
<guid>https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages</guid>
<title>Slack Consolidate: a slackbot built with Python and Supabase</title>
<link>https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages</link>
<description>Different approaches for tracking visitor counts with PostgreSQL.</description>
<description>A slackbot to consolidate messages from different channels using Supabase, Slack SDK and Python</description>
<pubDate>Mon, 08 Aug 2022 03:03:00</pubDate>
</item>
<item>
@@ -19,742 +25,742 @@
<title>Supabase Beta July 2022</title>
<link>https://supabase.com/blog/supabase-beta-update-july-2022</link>
<description>Launch Week Golden Tickets, Flutter SDK 1.0 Developer Preview and more...</description>
<pubDate>Tue, 02 Aug 2022 03:03:00</pubDate>
<pubDate>Tue, 02 Aug 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview</guid>
<title>Supabase Flutter SDK 1.0 Developer Preview</title>
<link>https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview</link>
<description>Supabase Flutter SDK is getting a major update and we need your help making it better.</description>
<pubDate>Mon, 01 Aug 2022 03:03:00</pubDate>
<pubDate>Mon, 01 Aug 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/seen-by-in-postgresql</guid>
<title>Implementing "seen by" functionality with Postgres</title>
<link>https://supabase.com/blog/seen-by-in-postgresql</link>
<description>Different approaches for tracking visitor counts with PostgreSQL.</description>
<pubDate>Sun, 17 Jul 2022 03:03:00</pubDate>
<pubDate>Sun, 17 Jul 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support</guid>
<title>Revamped Auth Helpers for Supabase (with SvelteKit support)</title>
<link>https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support</link>
<description>Supabase Auth Helpers now have improved developer experience, Sveltekit support, and more.</description>
<pubDate>Tue, 12 Jul 2022 03:03:00</pubDate>
<pubDate>Tue, 12 Jul 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/beta-update-june-2022</guid>
<title>Supabase Beta June 2022</title>
<link>https://supabase.com/blog/beta-update-june-2022</link>
<description>Auth Helpers, Unlimited Free Projects, CLI and more...</description>
<pubDate>Tue, 05 Jul 2022 03:03:00</pubDate>
<pubDate>Tue, 05 Jul 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/flutter-tutorial-building-a-chat-app</guid>
<title>Flutter Tutorial: building a Flutter chat app</title>
<link>https://supabase.com/blog/flutter-tutorial-building-a-chat-app</link>
<description>How to create a real time chat app using Flutter.</description>
<pubDate>Wed, 29 Jun 2022 03:03:00</pubDate>
<pubDate>Wed, 29 Jun 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/visualizing-supabase-data-using-metabase</guid>
<title>Visualizing Supabase Data using Metabase</title>
<link>https://supabase.com/blog/visualizing-supabase-data-using-metabase</link>
<description>How to create different kinds of charts out of data stored in Supabase using Metabase.</description>
<pubDate>Tue, 28 Jun 2022 03:03:00</pubDate>
<pubDate>Tue, 28 Jun 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</guid>
<title>Partial data dumps using Postgres Row Level Security</title>
<link>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</link>
<description>Using RLS to create seed files for local PostgreSQL testing.</description>
<pubDate>Mon, 27 Jun 2022 03:03:00</pubDate>
<pubDate>Mon, 27 Jun 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/loading-data-supabase-python</guid>
<title>Python data loading with Supabase</title>
<link>https://supabase.com/blog/loading-data-supabase-python</link>
<description>An example of how to load data into Supabase using supabase-py</description>
<pubDate>Thu, 16 Jun 2022 03:03:00</pubDate>
<pubDate>Thu, 16 Jun 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/beta-update-may-2022</guid>
<title>Supabase Beta May 2022</title>
<link>https://supabase.com/blog/beta-update-may-2022</link>
<description>Product and community updates including wildcard auth redirects, edge functions with webhooks, and Prometheus endpoints for everybody.</description>
<pubDate>Tue, 31 May 2022 03:03:00</pubDate>
<pubDate>Tue, 31 May 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together</guid>
<title>How Mike Lyndon is using Supabase to accelerate development of AllPullTogether</title>
<link>https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together</link>
<description>Mike Lyndon is learning web development as he builds AllPullTogether, and Supabase is helping him accelerate what he can accomplish.</description>
<pubDate>Wed, 25 May 2022 03:03:00</pubDate>
<pubDate>Wed, 25 May 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/partner-gallery-works-with-supabase</guid>
<title>Works With Supabase - announcing our Partner Gallery</title>
<link>https://supabase.com/blog/partner-gallery-works-with-supabase</link>
<description>Introducing our Partner Gallery - open source and made with Supabase.</description>
<pubDate>Tue, 19 Apr 2022 03:03:00</pubDate>
<pubDate>Tue, 19 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/bring-the-func-hackathon-winners</guid>
<title>Bring the Func Hackathon Winners 2022</title>
<link>https://supabase.com/blog/bring-the-func-hackathon-winners</link>
<description>Celebrating many amazing OSS Hackathon projects using GraphQL and Edge Functions.</description>
<pubDate>Sun, 17 Apr 2022 03:03:00</pubDate>
<pubDate>Sun, 17 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/beta-update-march-2022</guid>
<title>Supabase Beta March 2022</title>
<link>https://supabase.com/blog/beta-update-march-2022</link>
<description>Functions, GraphQL, and much more.</description>
<pubDate>Thu, 14 Apr 2022 03:03:00</pubDate>
<pubDate>Thu, 14 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabrew</guid>
<title>Supabrew - Never Code Thirsty</title>
<link>https://supabase.com/blog/supabrew</link>
<description>A light and refreshing non-alcoholic beer for devs.</description>
<pubDate>Fri, 01 Apr 2022 03:03:00</pubDate>
<pubDate>Fri, 01 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-realtime-with-multiplayer-features</guid>
<title>Supabase Realtime, with Multiplayer Features</title>
<link>https://supabase.com/blog/supabase-realtime-with-multiplayer-features</link>
<description>Today we're announced Realtime, with multiplayer features. Realtime enables broadcast, presence, and listening to database changes delivered over WebSockets.</description>
<pubDate>Fri, 01 Apr 2022 03:03:00</pubDate>
<pubDate>Fri, 01 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/hackathon-bring-the-func</guid>
<title>Hackathon: Bring the Func(🕺)</title>
<link>https://supabase.com/blog/hackathon-bring-the-func</link>
<description>Build open-source projects with our latest features, win limited edition swag and plant a tree!</description>
<pubDate>Fri, 01 Apr 2022 03:03:00</pubDate>
<pubDate>Fri, 01 Apr 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-edge-functions</guid>
<title>Edge Functions are now available in Supabase</title>
<link>https://supabase.com/blog/supabase-edge-functions</link>
<description>Today we're launching Edge Functions. Edge Functions let you execute Typescript code close to your users, no matter where they're located.</description>
<pubDate>Wed, 30 Mar 2022 03:03:00</pubDate>
<pubDate>Wed, 30 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-enterprise</guid>
<title>Introducing Supabase Enterprise</title>
<link>https://supabase.com/blog/supabase-enterprise</link>
<description>Today we are releasing Supabase Enterprise, a suite of features to scale your project.</description>
<pubDate>Tue, 29 Mar 2022 03:03:00</pubDate>
<pubDate>Tue, 29 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/graphql-now-available</guid>
<title>GraphQL is now available in Supabase</title>
<link>https://supabase.com/blog/graphql-now-available</link>
<description>GraphQL support is now in general availability on the Supabase platform via our open source PostgreSQL extension, pg_graphql (beta).</description>
<pubDate>Mon, 28 Mar 2022 03:03:00</pubDate>
<pubDate>Mon, 28 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/community-day</guid>
<title>Community Day</title>
<link>https://supabase.com/blog/community-day</link>
<description>Kicking off Launch Week 4 with contributors, partners, and friends.</description>
<pubDate>Sun, 27 Mar 2022 03:03:00</pubDate>
<pubDate>Sun, 27 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-launch-week-four</guid>
<title>Supabase Launch Week 4</title>
<link>https://supabase.com/blog/supabase-launch-week-four</link>
<description>Launch Week 4: One new feature every day for an entire week. Starting Monday 28th March.</description>
<pubDate>Thu, 24 Mar 2022 03:03:00</pubDate>
<pubDate>Thu, 24 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/should-i-open-source-my-company</guid>
<title>Should I Open Source my Company?</title>
<link>https://supabase.com/blog/should-i-open-source-my-company</link>
<description>The unexpected upsides of building in public</description>
<pubDate>Thu, 24 Mar 2022 03:03:00</pubDate>
<pubDate>Thu, 24 Mar 2022 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/audit</guid>
<title>Postgres Auditing in 150 lines of SQL</title>
<link>https://supabase.com/blog/audit</link>
<description>PostgreSQL has a robust set of features which we can leverage to create a generic auditing solution in 150 lines of SQL.</description>
<pubDate>Mon, 07 Mar 2022 03:03:00</pubDate>
<pubDate>Mon, 07 Mar 2022 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-january-2022</guid>
<title>Supabase Beta January 2022</title>
<link>https://supabase.com/blog/supabase-beta-january-2022</link>
<description>New auth providers, SMS providers, and new videos.</description>
<pubDate>Mon, 21 Feb 2022 03:03:00</pubDate>
<pubDate>Mon, 21 Feb 2022 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-december-2021</guid>
<title>Supabase Beta December 2021</title>
<link>https://supabase.com/blog/supabase-beta-december-2021</link>
<description>New crypto extension, Postgres videos, and a bunch of cool integrations.</description>
<pubDate>Wed, 19 Jan 2022 03:03:00</pubDate>
<pubDate>Wed, 19 Jan 2022 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/product-hunt-golden-kitty-awards-2021</guid>
<title>Golden Kitty Awards Ceremony Watch Party with Supabase</title>
<link>https://supabase.com/blog/product-hunt-golden-kitty-awards-2021</link>
<description>Hang out with us while watching the Product Hunt Golden Kitty Awards Ceremony</description>
<pubDate>Wed, 19 Jan 2022 03:03:00</pubDate>
<pubDate>Wed, 19 Jan 2022 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/holiday-hackdays-winners-2021</guid>
<title>Holiday Hackdays Winners 2021</title>
<link>https://supabase.com/blog/holiday-hackdays-winners-2021</link>
<description>Celebrating many amazing projects submitted to our Holiday Hackdays Hackathon.</description>
<pubDate>Thu, 16 Dec 2021 03:03:00</pubDate>
<pubDate>Thu, 16 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/beta-november-2021-launch-week-recap</guid>
<title>Supabase Beta November 2021: Launch Week Recap</title>
<link>https://supabase.com/blog/beta-november-2021-launch-week-recap</link>
<description>We wrapped up November with Supabase's third Launch Week. Here's all the awesome stuff that got shipped ...</description>
<pubDate>Tue, 14 Dec 2021 03:03:00</pubDate>
<pubDate>Tue, 14 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-holiday-hackdays-hackathon</guid>
<title>Kicking off the Holiday Hackdays</title>
<link>https://supabase.com/blog/supabase-holiday-hackdays-hackathon</link>
<description>Build cool stuff and celebrate open-source software with us during the Holiday Hackdays!</description>
<pubDate>Thu, 02 Dec 2021 03:03:00</pubDate>
<pubDate>Thu, 02 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pg-graphql</guid>
<title>pg_graphql: A GraphQL extension for PostgreSQL</title>
<link>https://supabase.com/blog/pg-graphql</link>
<description>GraphQL support is in development for PostgreSQL + Supabase.</description>
<pubDate>Thu, 02 Dec 2021 03:03:00</pubDate>
<pubDate>Thu, 02 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/launch-week-three-friday-five-more-things</guid>
<title>Five more things</title>
<link>https://supabase.com/blog/launch-week-three-friday-five-more-things</link>
<description>It's never just one more thing!</description>
<pubDate>Thu, 02 Dec 2021 03:03:00</pubDate>
<pubDate>Thu, 02 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-acquires-logflare</guid>
<title>Supabase acquires Logflare</title>
<link>https://supabase.com/blog/supabase-acquires-logflare</link>
<description>Today, we're ecstatic to announce that Logflare is joining Supabase.</description>
<pubDate>Wed, 01 Dec 2021 03:03:00</pubDate>
<pubDate>Wed, 01 Dec 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/realtime-row-level-security-in-postgresql</guid>
<title>Realtime Postgres RLS now available on Supabase</title>
<link>https://supabase.com/blog/realtime-row-level-security-in-postgresql</link>
<description>Realtime database changes are now broadcast to authenticated users, respecting the same PostgreSQL policies that you use for Row Level Security.</description>
<pubDate>Tue, 30 Nov 2021 03:03:00</pubDate>
<pubDate>Tue, 30 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-studio</guid>
<title>Supabase Studio</title>
<link>https://supabase.com/blog/supabase-studio</link>
<description>The same Dashboard that you're using on our Platform is now available for local development and Self-Hosting.</description>
<pubDate>Mon, 29 Nov 2021 03:03:00</pubDate>
<pubDate>Mon, 29 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/community-day</guid>
<title>Community Day</title>
<link>https://supabase.com/blog/community-day</link>
<description>Kicking off launch week by highlighting the communities around Supabase.</description>
<pubDate>Sun, 28 Nov 2021 03:03:00</pubDate>
<pubDate>Sun, 28 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/whats-new-in-postgres-14</guid>
<title>New in PostgreSQL 14: What every developer should know</title>
<link>https://supabase.com/blog/whats-new-in-postgres-14</link>
<description>A quick look at some new features and functionality in PostgreSQL 14.</description>
<pubDate>Sat, 27 Nov 2021 03:03:00</pubDate>
<pubDate>Sat, 27 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgrest-9</guid>
<title>PostgREST 9</title>
<link>https://supabase.com/blog/postgrest-9</link>
<description>New features and updates in PostgREST version 9.</description>
<pubDate>Fri, 26 Nov 2021 03:03:00</pubDate>
<pubDate>Fri, 26 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-launch-week-the-trilogy</guid>
<title>Supabase Launch Week III: Holiday Special</title>
<link>https://supabase.com/blog/supabase-launch-week-the-trilogy</link>
<description>Tis the season to be shipping.</description>
<pubDate>Thu, 25 Nov 2021 03:03:00</pubDate>
<pubDate>Thu, 25 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-how-we-launch</guid>
<title>How we launch at Supabase</title>
<link>https://supabase.com/blog/supabase-how-we-launch</link>
<description>The history and methodology of Supabase Launch Week.</description>
<pubDate>Thu, 25 Nov 2021 03:03:00</pubDate>
<pubDate>Thu, 25 Nov 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-october-2021</guid>
<title>Supabase Beta October 2021</title>
<link>https://supabase.com/blog/supabase-beta-october-2021</link>
<description>Three new Auth providers, multi-schema support, and we're gearing up for another Launch Week.</description>
<pubDate>Sat, 06 Nov 2021 03:03:00</pubDate>
<pubDate>Sat, 06 Nov 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-series-a</guid>
<title>Supabase $30m Series A</title>
<link>https://supabase.com/blog/supabase-series-a</link>
<description>Supabase just raised $30M, bringing our total funding to $36M.</description>
<pubDate>Wed, 27 Oct 2021 03:03:00</pubDate>
<pubDate>Wed, 27 Oct 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours</guid>
<title>Replenysh uses Supabase to implement OTP in less than 24-hours</title>
<link>https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours</link>
<description>Learn how Replenysh uses Supabase to power the circular economy, redefining how brands interact with their customers and products.</description>
<pubDate>Mon, 18 Oct 2021 03:03:00</pubDate>
<pubDate>Mon, 18 Oct 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/hacktoberfest-hackathon-winners-2021</guid>
<title>Hacktoberfest Hackathon Winners 2021</title>
<link>https://supabase.com/blog/hacktoberfest-hackathon-winners-2021</link>
<description>Celebrating many amazing projects submitted to our Hacktoberfest Hackathon.</description>
<pubDate>Wed, 13 Oct 2021 03:03:00</pubDate>
<pubDate>Wed, 13 Oct 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-sept-2021</guid>
<title>Supabase Beta Sept 2021</title>
<link>https://supabase.com/blog/supabase-beta-sept-2021</link>
<description>Hackathon, Aborting request, UI updates, and now Hiring.</description>
<pubDate>Sun, 03 Oct 2021 03:03:00</pubDate>
<pubDate>Sun, 03 Oct 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021</guid>
<title>Supabase Hacktoberfest Hackathon 2021</title>
<link>https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021</link>
<description>We're running another Supabase Hackathon during Hacktoberfest!</description>
<pubDate>Mon, 27 Sep 2021 03:03:00</pubDate>
<pubDate>Mon, 27 Sep 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-august-2021</guid>
<title>Supabase Beta August 2021</title>
<link>https://supabase.com/blog/supabase-beta-august-2021</link>
<description>Fundraising, Realtime Security, custom SMS templates, and deployments in South Korea.</description>
<pubDate>Thu, 09 Sep 2021 03:03:00</pubDate>
<pubDate>Thu, 09 Sep 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-july-2021</guid>
<title>Supabase Beta July 2021</title>
<link>https://supabase.com/blog/supabase-beta-july-2021</link>
<description>Discord Logins, Vercel Integration, Full text search, and OAuth guides.</description>
<pubDate>Wed, 11 Aug 2021 03:03:00</pubDate>
<pubDate>Wed, 11 Aug 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/hackathon-winners</guid>
<title>Open Source Hackathon Winners</title>
<link>https://supabase.com/blog/hackathon-winners</link>
<description>Let the medal ceremony begin for the best projects submitted during the Supabase Hackathon.</description>
<pubDate>Sun, 08 Aug 2021 03:03:00</pubDate>
<pubDate>Sun, 08 Aug 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-swag-store</guid>
<title>Supabase Swag Store</title>
<link>https://supabase.com/blog/supabase-swag-store</link>
<description>Today we are officially launching the Supabase Swag Store.</description>
<pubDate>Thu, 29 Jul 2021 03:03:00</pubDate>
<pubDate>Thu, 29 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-functions-updates</guid>
<title>Updates for Supabase Functions</title>
<link>https://supabase.com/blog/supabase-functions-updates</link>
<description>The question on everyone's mind - are we launching Supabase Functions? Well, it's complicated.</description>
<pubDate>Thu, 29 Jul 2021 03:03:00</pubDate>
<pubDate>Thu, 29 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/1-the-supabase-hackathon</guid>
<title>The Supabase Hackathon</title>
<link>https://supabase.com/blog/1-the-supabase-hackathon</link>
<description>A whole week of Hacking for Fun and Prizes.</description>
<pubDate>Thu, 29 Jul 2021 03:03:00</pubDate>
<pubDate>Thu, 29 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-reports-and-metrics</guid>
<title>Supabase Reports and Metrics</title>
<link>https://supabase.com/blog/supabase-reports-and-metrics</link>
<description>We're exposing a full set of metrics in your projects, so that you can build better (and faster) products for your users.</description>
<pubDate>Wed, 28 Jul 2021 03:03:00</pubDate>
<pubDate>Wed, 28 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-auth-passwordless-sms-login</guid>
<title>Supabase Auth v2: Phone Auth now available</title>
<link>https://supabase.com/blog/supabase-auth-passwordless-sms-login</link>
<description>Phone Auth is available today on all new and existing Supabase projects.</description>
<pubDate>Tue, 27 Jul 2021 03:03:00</pubDate>
<pubDate>Tue, 27 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/mobbin-supabase-200000-users</guid>
<title>Mobbin uses Supabase to authenticate 200,000 users</title>
<link>https://supabase.com/blog/mobbin-supabase-200000-users</link>
<description>Learn how Mobbin migrated 200,000 users from Firebase for a better authentication experience.</description>
<pubDate>Tue, 27 Jul 2021 03:03:00</pubDate>
<pubDate>Tue, 27 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/storage-beta</guid>
<title>Supabase Storage now in Beta</title>
<link>https://supabase.com/blog/storage-beta</link>
<description>Supabase Storage moves into Beta.</description>
<pubDate>Mon, 26 Jul 2021 03:03:00</pubDate>
<pubDate>Mon, 26 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/spot-flutter-with-postgres</guid>
<title>Spot: a video sharing app built with Flutter</title>
<link>https://supabase.com/blog/spot-flutter-with-postgres</link>
<description>Spot is a geolocation-based video-sharing app with some social networking features.</description>
<pubDate>Mon, 26 Jul 2021 03:03:00</pubDate>
<pubDate>Mon, 26 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-postgres-13</guid>
<title>Supabase is now on Postgres 13.3</title>
<link>https://supabase.com/blog/supabase-postgres-13</link>
<description>From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.</description>
<pubDate>Sun, 25 Jul 2021 03:03:00</pubDate>
<pubDate>Sun, 25 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-community-day</guid>
<title>Supabase Community Day</title>
<link>https://supabase.com/blog/supabase-community-day</link>
<description>Community Day</description>
<pubDate>Sun, 25 Jul 2021 03:03:00</pubDate>
<pubDate>Sun, 25 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/epsilon3-self-hosting</guid>
<title>Epsilon3 Self-Host Supabase To Revolutionize Space Operations </title>
<link>https://supabase.com/blog/epsilon3-self-hosting</link>
<description>Learn how the team at Epsilon3 use Supabase to help teams execute secure and reliable operations in an industry that project spend runs into the billions.</description>
<pubDate>Sun, 25 Jul 2021 03:03:00</pubDate>
<pubDate>Sun, 25 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-launch-week-sql</guid>
<title>Supabase Launch Week II: The SQL</title>
<link>https://supabase.com/blog/supabase-launch-week-sql</link>
<description>Five days of Supabase. Again.</description>
<pubDate>Wed, 21 Jul 2021 03:03:00</pubDate>
<pubDate>Wed, 21 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/roles-postgres-hooks</guid>
<title>Protecting reserved roles with PostgreSQL Hooks</title>
<link>https://supabase.com/blog/roles-postgres-hooks</link>
<description>Using Postgres Hooks to protect functionality in your Postgres database.</description>
<pubDate>Thu, 01 Jul 2021 03:03:00</pubDate>
<pubDate>Thu, 01 Jul 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-june-2021</guid>
<title>Supabase Beta June 2021</title>
<link>https://supabase.com/blog/supabase-beta-june-2021</link>
<description>Discord Logins, Vercel Integration, Full text search, and OAuth guides.</description>
<pubDate>Tue, 01 Jun 2021 03:03:00</pubDate>
<pubDate>Tue, 01 Jun 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-may-2021</guid>
<title>Supabase Beta May 2021</title>
<link>https://supabase.com/blog/supabase-beta-may-2021</link>
<description>Apple &amp; Twitter Logins, Supabase Grid, Go &amp; Swift Libraries.</description>
<pubDate>Tue, 01 Jun 2021 03:03:00</pubDate>
<pubDate>Tue, 01 Jun 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-april-2021</guid>
<title>Supabase Beta April 2021</title>
<link>https://supabase.com/blog/supabase-beta-april-2021</link>
<description>Supabase "gardening" - stability, security, and community support.</description>
<pubDate>Tue, 04 May 2021 03:03:00</pubDate>
<pubDate>Tue, 04 May 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-march-2021</guid>
<title>Supabase Beta March 2021</title>
<link>https://supabase.com/blog/supabase-beta-march-2021</link>
<description>Launch week, Storage, Supabase CLI, Connection Pooling, Supabase UI, and Pricing.</description>
<pubDate>Mon, 05 Apr 2021 03:03:00</pubDate>
<pubDate>Mon, 05 Apr 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-workflows</guid>
<title>Workflows are coming to Supabase</title>
<link>https://supabase.com/blog/supabase-workflows</link>
<description>Functions are great, but you know what's better?</description>
<pubDate>Thu, 01 Apr 2021 03:03:00</pubDate>
<pubDate>Thu, 01 Apr 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-pgbouncer</guid>
<title>PgBouncer is now available in Supabase</title>
<link>https://supabase.com/blog/supabase-pgbouncer</link>
<description>Better support for Serverless and Postgres.</description>
<pubDate>Thu, 01 Apr 2021 03:03:00</pubDate>
<pubDate>Thu, 01 Apr 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-dot-com</guid>
<title>Supabase Dot Com</title>
<link>https://supabase.com/blog/supabase-dot-com</link>
<description>The Supabase Domain name is changing.</description>
<pubDate>Thu, 01 Apr 2021 03:03:00</pubDate>
<pubDate>Thu, 01 Apr 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-nft-marketplace</guid>
<title>Supabase Launches NFT Marketplace</title>
<link>https://supabase.com/blog/supabase-nft-marketplace</link>
<description>A fully encrypted NFT platform to protect and transact your digital assets</description>
<pubDate>Thu, 01 Apr 2021 03:03:00</pubDate>
<pubDate>Thu, 01 Apr 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-cli</guid>
<title>Supabase CLI</title>
<link>https://supabase.com/blog/supabase-cli</link>
<description>Local development, database migrations, and self-hosting.</description>
<pubDate>Wed, 31 Mar 2021 03:03:00</pubDate>
<pubDate>Wed, 31 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-storage</guid>
<title>Storage is now available in Supabase</title>
<link>https://supabase.com/blog/supabase-storage</link>
<description>Launching Supabase Storage and how you can use it in your apps</description>
<pubDate>Tue, 30 Mar 2021 03:03:00</pubDate>
<pubDate>Tue, 30 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/pricing</guid>
<title>Supabase Beta Pricing</title>
<link>https://supabase.com/blog/pricing</link>
<description>Supabase launches Beta pricing structure</description>
<pubDate>Mon, 29 Mar 2021 03:03:00</pubDate>
<pubDate>Mon, 29 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/launch-week</guid>
<title>Launch week</title>
<link>https://supabase.com/blog/launch-week</link>
<description>Five days of Supabase.</description>
<pubDate>Wed, 24 Mar 2021 03:03:00</pubDate>
<pubDate>Wed, 24 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/angels-of-supabase</guid>
<title>Angels of Supabase</title>
<link>https://supabase.com/blog/angels-of-supabase</link>
<description>Meet the investors of Supabase.</description>
<pubDate>Wed, 24 Mar 2021 03:03:00</pubDate>
<pubDate>Wed, 24 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/In-The-Loop</guid>
<title>Developers stay up to date with intheloop.dev</title>
<link>https://supabase.com/blog/In-The-Loop</link>
<description>Learn why Kevin is building intheloop.dev with Supabase</description>
<pubDate>Mon, 22 Mar 2021 03:03:00</pubDate>
<pubDate>Mon, 22 Mar 2021 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/using-supabase-replit</guid>
<title>Using Supabase in Replit</title>
<link>https://supabase.com/blog/using-supabase-replit</link>
<description>Free hosted relational database from within your node.js repl</description>
<pubDate>Thu, 11 Mar 2021 03:03:00</pubDate>
<pubDate>Thu, 11 Mar 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders</guid>
<title>Toad, a link shortener with simple APIs for low-coders</title>
<link>https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders</link>
<description>An easy-to-use link shortening tool with simple APIs</description>
<pubDate>Mon, 08 Mar 2021 03:03:00</pubDate>
<pubDate>Mon, 08 Mar 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgres-as-a-cron-server</guid>
<title>Postgres as a CRON Server</title>
<link>https://supabase.com/blog/postgres-as-a-cron-server</link>
<description>Running repetitive tasks with your Postgres database.</description>
<pubDate>Fri, 05 Mar 2021 03:03:00</pubDate>
<pubDate>Fri, 05 Mar 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-february-2021</guid>
<title>Supabase Beta February 2021</title>
<link>https://supabase.com/blog/supabase-beta-february-2021</link>
<description>One year of building.</description>
<pubDate>Tue, 02 Mar 2021 03:03:00</pubDate>
<pubDate>Tue, 02 Mar 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/cracking-postgres-interview</guid>
<title>Cracking PostgreSQL Interview Questions</title>
<link>https://supabase.com/blog/cracking-postgres-interview</link>
<description>Understand the top PostgreSQL Interview Questions</description>
<pubDate>Sat, 27 Feb 2021 03:03:00</pubDate>
<pubDate>Sat, 27 Feb 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/case-study-roboflow</guid>
<title>Roboflow.com choose Supabase to power Paint.wtf leaderboard</title>
<link>https://supabase.com/blog/case-study-roboflow</link>
<description>Learn how Roboflow.com used Supabase to build their Paint.wtf leaderboard</description>
<pubDate>Tue, 09 Feb 2021 03:03:00</pubDate>
<pubDate>Tue, 09 Feb 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-january-2021</guid>
<title>Supabase Beta January 2021</title>
<link>https://supabase.com/blog/supabase-beta-january-2021</link>
<description>Eleven months of building.</description>
<pubDate>Tue, 02 Feb 2021 03:03:00</pubDate>
<pubDate>Tue, 02 Feb 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-beta-december-2020</guid>
<title>Supabase Beta December 2020</title>
<link>https://supabase.com/blog/supabase-beta-december-2020</link>
<description>Ten months of building.</description>
<pubDate>Sat, 02 Jan 2021 03:03:00</pubDate>
<pubDate>Sat, 02 Jan 2021 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-dashboard-performance</guid>
<title>Making the Supabase Dashboard Supa-fast</title>
<link>https://supabase.com/blog/supabase-dashboard-performance</link>
<description>Improving the performance of the Supabase dashboard</description>
<pubDate>Sun, 13 Dec 2020 03:03:00</pubDate>
<pubDate>Sun, 13 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-striveschool</guid>
<title>Supabase Partners With Strive School To Help Teach Open Source</title>
<link>https://supabase.com/blog/supabase-striveschool</link>
<description>Supabase Partners With Strive School To Help Teach Open Source To The Next Generation Of Developers</description>
<pubDate>Wed, 02 Dec 2020 03:03:00</pubDate>
<pubDate>Wed, 02 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/case-study-xendit</guid>
<title>Xendit Built a Counter-Fraud Watchlist for the Fintech Industry</title>
<link>https://supabase.com/blog/case-study-xendit</link>
<description>See how Xendit use Supabase to build a full-text search engine.</description>
<pubDate>Wed, 02 Dec 2020 03:03:00</pubDate>
<pubDate>Wed, 02 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/case-study-tayfa</guid>
<title>TAYFA Built a No-Code Website Builder in Seven Days</title>
<link>https://supabase.com/blog/case-study-tayfa</link>
<description>See how Tayfa went from idea to paying customer in less than 30 days.</description>
<pubDate>Wed, 02 Dec 2020 03:03:00</pubDate>
<pubDate>Wed, 02 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/case-study-monitoro</guid>
<title>Monitoro Built a Web Crawler Handling Millions of API Requests</title>
<link>https://supabase.com/blog/case-study-monitoro</link>
<description>See how Monitoro built an automated scraping platform using Supabase.</description>
<pubDate>Wed, 02 Dec 2020 03:03:00</pubDate>
<pubDate>Wed, 02 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-november-2020</guid>
<title>Supabase Alpha November 2020</title>
<link>https://supabase.com/blog/supabase-alpha-november-2020</link>
<description>Nine months of building.</description>
<pubDate>Tue, 01 Dec 2020 03:03:00</pubDate>
<pubDate>Tue, 01 Dec 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-views</guid>
<title>Postgres Views</title>
<link>https://supabase.com/blog/postgresql-views</link>
<description>Creating and using a view in PostgreSQL.</description>
<pubDate>Wed, 18 Nov 2020 03:03:00</pubDate>
<pubDate>Wed, 18 Nov 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-october-2020</guid>
<title>Supabase Alpha October 2020</title>
<link>https://supabase.com/blog/supabase-alpha-october-2020</link>
<description>Eight months of building.</description>
<pubDate>Mon, 02 Nov 2020 03:03:00</pubDate>
<pubDate>Mon, 02 Nov 2020 07:07:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/improved-dx</guid>
<title>Supabase.js 1.0</title>
<link>https://supabase.com/blog/improved-dx</link>
<description>We're releasing a new version of our Supabase client with some awesome new improvements.</description>
<pubDate>Fri, 30 Oct 2020 03:03:00</pubDate>
<pubDate>Fri, 30 Oct 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-september-2020</guid>
<title>Supabase Alpha September 2020</title>
<link>https://supabase.com/blog/supabase-alpha-september-2020</link>
<description>Seven months of building.</description>
<pubDate>Sat, 03 Oct 2020 03:03:00</pubDate>
<pubDate>Sat, 03 Oct 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-hacktoberfest-2020</guid>
<title>Supabase Hacktoberfest 2020</title>
<link>https://supabase.com/blog/supabase-hacktoberfest-2020</link>
<description>Join us for a celebration of open source software and learn how to contribute to Supabase.</description>
<pubDate>Fri, 11 Sep 2020 03:03:00</pubDate>
<pubDate>Fri, 11 Sep 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-august-2020</guid>
<title>Supabase Alpha August 2020</title>
<link>https://supabase.com/blog/supabase-alpha-august-2020</link>
<description>Six months of building</description>
<pubDate>Thu, 03 Sep 2020 03:03:00</pubDate>
<pubDate>Thu, 03 Sep 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-auth</guid>
<title>Supabase Auth</title>
<link>https://supabase.com/blog/supabase-auth</link>
<description>Authenticate and authorize your users with Supabase Auth</description>
<pubDate>Wed, 05 Aug 2020 03:03:00</pubDate>
<pubDate>Wed, 05 Aug 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-july-2020</guid>
<title>Supabase Alpha July 2020</title>
<link>https://supabase.com/blog/supabase-alpha-july-2020</link>
<description>Five months of building</description>
<pubDate>Sun, 02 Aug 2020 03:03:00</pubDate>
<pubDate>Sun, 02 Aug 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/continuous-postgresql-backup-walg</guid>
<title>Continuous PostgreSQL Backups using WAL-G</title>
<link>https://supabase.com/blog/continuous-postgresql-backup-walg</link>
<description>Have you ever wanted to restore your database's state to a particular moment in time? This post explains how, using WAL-G.</description>
<pubDate>Sun, 02 Aug 2020 03:03:00</pubDate>
<pubDate>Sun, 02 Aug 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/alpha-launch-postmortem</guid>
<title>Alpha Launch Postmortem</title>
<link>https://supabase.com/blog/alpha-launch-postmortem</link>
<description>Everything that went wrong with Supabase's launch</description>
<pubDate>Fri, 10 Jul 2020 03:03:00</pubDate>
<pubDate>Fri, 10 Jul 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-templates</guid>
<title>What are PostgreSQL Templates?</title>
<link>https://supabase.com/blog/postgresql-templates</link>
<description>What are PostgreSQL templates and what are they used for?</description>
<pubDate>Thu, 09 Jul 2020 03:03:00</pubDate>
<pubDate>Thu, 09 Jul 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/postgresql-physical-logical-backups</guid>
<title>Physical vs Logical Backups in PostgreSQL</title>
<link>https://supabase.com/blog/postgresql-physical-logical-backups</link>
<description>What are physical and logical backups in Postgres?</description>
<pubDate>Tue, 07 Jul 2020 03:03:00</pubDate>
<pubDate>Tue, 07 Jul 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-june-2020</guid>
<title>Supabase Alpha June 2020</title>
<link>https://supabase.com/blog/supabase-alpha-june-2020</link>
<description>Four months of building</description>
<pubDate>Wed, 01 Jul 2020 03:03:00</pubDate>
<pubDate>Wed, 01 Jul 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-steve-chavez</guid>
<title>Steve Chavez has joined Supabase</title>
<link>https://supabase.com/blog/supabase-steve-chavez</link>
<description>Steve joins Supabase to help build Auth.</description>
<pubDate>Mon, 15 Jun 2020 03:03:00</pubDate>
<pubDate>Mon, 15 Jun 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-may-2020</guid>
<title>Supabase Alpha May 2020</title>
<link>https://supabase.com/blog/supabase-alpha-may-2020</link>
<description>Three months of building</description>
<pubDate>Mon, 01 Jun 2020 03:03:00</pubDate>
<pubDate>Mon, 01 Jun 2020 06:06:00</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/supabase-alpha-april-2020</guid>
<title>Supabase Alpha April 2020</title>
<link>https://supabase.com/blog/supabase-alpha-april-2020</link>
<description>Two months of building</description>
<pubDate>Mon, 01 Jun 2020 03:03:00</pubDate>
<pubDate>Mon, 01 Jun 2020 06:06:00</pubDate>
</item>
</channel>
@@ -1,6 +1,6 @@
import { useContext, useState, useRef } from 'react'
import { useContext, useState } from 'react'
import { observer } from 'mobx-react-lite'
import { Button, Modal, Input, IconPlus, IconMail } from '@supabase/ui'
import { Button, Modal, Input, IconPlus, IconMail, Form } from '@supabase/ui'
import { useStore } from 'hooks'
import { post } from 'lib/common/fetch'
@@ -8,44 +8,32 @@ import { API_URL } from 'lib/constants'
import { PageContext } from 'pages/project/[ref]/auth/users'
const InviteUserModal = () => {
const PageState: any = useContext(PageContext)
const inputRef = useRef<any>(null)
const { ui } = useStore()
const PageState: any = useContext(PageContext)
const [visible, setVisible] = useState(false)
const [loading, setLoading] = useState(false)
const [emailValue, setEmailValue] = useState('')
function handleToggle() {
// reset data before showing modal again
if (!visible) {
setEmailValue('')
}
setVisible(!visible)
}
const handleToggle = () => setVisible(!visible)
function onInputChange(e: any) {
setEmailValue(e.target.value)
}
async function onInviteUser() {
const validate = (values: any) => {
const errors: any = {}
const emailValidateRegex =
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
if (!emailValidateRegex.test(emailValue)) {
inputRef?.current?.focus()
const message =
emailValue.trim() === ''
? 'Please enter a valid email'
: `${emailValue} is an invalid email`
ui.setNotification({ category: 'error', message: message })
return
if (values.email.length === 0) {
errors.email = 'Please enter a valid email'
} else if (!emailValidateRegex.test(values.email)) {
errors.email = `${values.email} is an invalid email`
}
setLoading(true)
const response = await post(`${API_URL}/auth/${PageState.projectRef}/invite`, {
email: emailValue,
})
return errors
}
const onInviteuser = async (values: any, { setSubmitting }: any) => {
setSubmitting(true)
const response = await post(`${API_URL}/auth/${PageState.projectRef}/invite`, {
email: values.email,
})
if (response.error) {
ui.setNotification({
category: 'error',
@@ -55,12 +43,12 @@ const InviteUserModal = () => {
PageState.fetchData(1)
ui.setNotification({
category: 'success',
message: `Sent invite email to ${emailValue}`,
message: `Sent invite email to ${values.email}`,
})
setVisible(false)
}
setLoading(false)
setVisible(false)
setSubmitting(false)
}
return (
@@ -69,38 +57,48 @@ const InviteUserModal = () => {
Invite
</Button>
<Modal
closable
hideFooter
size="small"
key="invite-user-modal"
visible={visible}
header="Invite new user"
hideFooter
header="Invite a new user"
onCancel={handleToggle}
closable
>
<div className="py-4 space-y-6">
<Modal.Content>
<Input
label="User email"
icon={<IconMail />}
descriptionText="Type in the full email address"
autoFocus
// @ts-ignore
ref={inputRef}
value={emailValue}
onChange={onInputChange}
type="email"
name="email"
id="email"
placeholder="User email"
className="w-full"
/>
</Modal.Content>
<Modal.Content>
<Button onClick={onInviteUser} size="small" loading={loading} disabled={loading} block>
Invite user
</Button>
</Modal.Content>
</div>
<Form
validateOnBlur
initialValues={{ email: '' }}
validate={validate}
onSubmit={onInviteuser}
>
{({ isSubmitting }: { isSubmitting: boolean }) => (
<div className="py-4 space-y-6">
<Modal.Content>
<Input
autoFocus
id="email"
className="w-full"
label="User email"
icon={<IconMail />}
type="email"
name="email"
placeholder="User email"
/>
</Modal.Content>
<Modal.Content>
<Button
block
size="small"
htmlType="submit"
loading={isSubmitting}
disabled={isSubmitting}
>
Invite user
</Button>
</Modal.Content>
</div>
)}
</Form>
</Modal>
</div>
)
@@ -29,6 +29,11 @@ const AddPaymentMethodForm: FC<Props> = ({ returnUrl, onCancel }) => {
setIsSaving(true)
if (document !== undefined) {
// [Joshen] This is to ensure that any 3DS popup from Stripe remains clickable
document.body.classList.add('!pointer-events-auto')
}
const { error } = await stripe.confirmSetup({
elements,
confirmParams: { return_url: returnUrl },
@@ -41,6 +46,10 @@ const AddPaymentMethodForm: FC<Props> = ({ returnUrl, onCancel }) => {
message: error?.message ?? ' Failed to save card details',
})
}
if (document !== undefined) {
document.body.classList.remove('!pointer-events-auto')
}
}
return (
@@ -3,6 +3,7 @@ import { FC } from 'react'
import { sum } from 'lodash'
import { useRouter } from 'next/router'
import { Button, Loading } from '@supabase/ui'
import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { checkPermissions, useStore, useFlag } from 'hooks'
@@ -38,7 +39,6 @@ const Subscription: FC<Props> = ({
}) => {
const { ui } = useStore()
const router = useRouter()
const isOrgOwner = ui.selectedOrganization?.is_owner
const enablePermissions = useFlag('enablePermissions')
const projectUpdateDisabled = useFlag('disableProjectCreationAndUpdate')
@@ -46,7 +46,7 @@ const Subscription: FC<Props> = ({
const canReadSubscription = checkPermissions(PermissionAction.READ, 'subscriptions')
const canUpdateSubscription = enablePermissions
? checkPermissions(PermissionAction.BILLING_WRITE, 'stripe.subscriptions')
: isOrgOwner
: ui.selectedOrganization?.is_owner
const isPayg = subscription?.tier.prod_id === STRIPE_PRODUCT_IDS.PAYG
const isEnterprise = subscription.tier.supabase_prod_id === PRICING_TIER_PRODUCT_IDS.ENTERPRISE
@@ -75,46 +75,51 @@ const Subscription: FC<Props> = ({
<h3 className="mb-0 text-xl">{subscription?.tier.name ?? '-'}</h3>
</div>
<div className="flex flex-col items-end space-y-2">
{isEnterprise ? (
<Button
disabled={!canUpdateSubscription || projectUpdateDisabled}
onClick={() =>
router.push(`/project/${project.ref}/settings/billing/update/enterprise`)
}
type="primary"
>
Change add-ons
</Button>
) : (
<Button
disabled={!canUpdateSubscription || projectUpdateDisabled}
onClick={() => router.push(`/project/${project.ref}/settings/billing/update`)}
type="primary"
>
Change subscription
</Button>
)}
{!canUpdateSubscription ? (
<>
{enablePermissions ? (
<p className="text-scale-1100 text-xs">
You need additional permissions to amend subscriptions
</p>
) : (
<p className="text-scale-1100 text-xs">
Only the organization owner can amend subscriptions
</p>
)}
</>
) : projectUpdateDisabled ? (
<p className="text-scale-1100 text-right text-xs">
Subscription changes are currently disabled
<br />
Our engineers are working on a fix
</p>
) : (
<div />
)}
<Tooltip.Root delayDuration={0}>
<Tooltip.Trigger>
<Button
disabled={!canUpdateSubscription || projectUpdateDisabled}
onClick={() => {
const url = isEnterprise
? `/project/${project.ref}/settings/billing/update/enterprise`
: `/project/${project.ref}/settings/billing/update`
router.push(url)
}}
type="primary"
>
{isEnterprise ? 'Change add-ons' : 'Change subscription'}
</Button>
</Tooltip.Trigger>
{!canUpdateSubscription || projectUpdateDisabled ? (
<Tooltip.Content side="bottom">
<Tooltip.Arrow className="radix-tooltip-arrow" />
<div
className={[
'border-scale-200 border text-center', //border
'bg-scale-100 rounded py-1 px-2 leading-none shadow', // background
].join(' ')}
>
<span className="text-scale-1200 text-xs">
{projectUpdateDisabled ? (
<>
Subscription changes are currently disabled.
<br />
Our engineers are working on a fix.
</>
) : !canUpdateSubscription && enablePermissions ? (
'You need additional permissions to amend subscriptions'
) : !canUpdateSubscription && !enablePermissions ? (
'Only the organization owner can amend subscriptions'
) : (
''
)}
</span>
</div>
</Tooltip.Content>
) : (
<></>
)}
</Tooltip.Root>
</div>
</div>
{paid && (
@@ -36,11 +36,16 @@ const MemberActions: FC<Props> = ({ members, member, roles }) => {
const isExpired = isInviteExpired(member?.invited_at ?? '')
const isPendingInviteAcceptance = member.invited_id
const roleId = member.role_ids?.[0] ?? -1
const canRemoveMember = enablePermissions
? rolesRemovable.includes((member?.role_ids ?? [-1])[0])
: true
const canResendInvite = checkPermissions(PermissionAction.CREATE, 'user_invites')
const canRevokeInvite = checkPermissions(PermissionAction.DELETE, 'user_invites')
const canResendInvite = checkPermissions(PermissionAction.CREATE, 'user_invites', {
resource: { role_id: roleId },
})
const canRevokeInvite = checkPermissions(PermissionAction.DELETE, 'user_invites', {
resource: { role_id: roleId },
})
const handleMemberDelete = async () => {
confirmAlert({
@@ -12,6 +12,7 @@ import { isInviteExpired, getUserDisplayName } from '../Organization.utils'
import Table from 'components/to-be-cleaned/Table'
import MemberActions from './MemberActions'
import RolesHelperModal from './RolesHelperModal/RolesHelperModal'
import { PageContext } from 'pages/org/[slug]/settings'
import { getRolesManagementPermissions } from './TeamSettings.utils'
@@ -84,7 +85,10 @@ const MembersView = () => {
head={[
<Table.th key="header-user">User</Table.th>,
<Table.th key="header-status"></Table.th>,
<Table.th key="header-role">Role</Table.th>,
<Table.th key="header-role" className="flex items-center space-x-2">
<span>Role</span>
{enablePermissions && <RolesHelperModal />}
</Table.th>,
<Table.th key="header-action"></Table.th>,
]}
body={[
@@ -97,7 +101,7 @@ const MembersView = () => {
const disableRoleEdit = !canRemoveRole || memberIsUser || memberIsPendingInvite
const validateSelectedRoleToChange = (roleId: any) => {
if (!role) return
if (!role || role.id === roleId) return
const selectedRole = (roles || []).find((role) => role.id === roleId)
const canAddRole = rolesAddable.includes(selectedRole?.id ?? -1)
@@ -167,14 +171,14 @@ const MembersView = () => {
value={role.id}
onChange={validateSelectedRoleToChange}
>
{roles.map((role: any) => (
{roles.map((r: any) => (
<Listbox.Option
key={role.id}
value={role.id}
label={role.name}
key={r.id}
value={r.id}
label={r.name}
disabled={disableRoleEdit}
>
{role.name}
{r.name}
</Listbox.Option>
))}
</Listbox>
@@ -194,7 +198,7 @@ const MembersView = () => {
</span>
</div>
</Tooltip.Content>
) : !canRemoveRole ? (
) : !memberIsUser && !canRemoveRole ? (
<Tooltip.Content side="bottom">
<Tooltip.Arrow className="radix-tooltip-arrow" />
<div
@@ -0,0 +1,246 @@
const ORGANIZATIONS_PERMISSIONS = {
title: 'Organization',
actions: [
{
description: 'Can change organization name',
permissions: {
owner: true,
admin: false,
developer: false,
},
},
{
description: 'Can delete organization',
permissions: {
owner: true,
admin: false,
developer: false,
},
},
],
}
const MEMBERS_MANAGEMENT_PERMISSIONS = {
title: 'Members',
actions: [
{
description: 'Can add an Owner',
permissions: {
owner: true,
admin: false,
developer: false,
},
},
{
description: 'Can remove an Owner',
permissions: {
owner: true,
admin: false,
developer: false,
},
},
{
description: 'Can add an Adminstrator',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can remove an Administrator',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can add a Developer',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can remove a Developer',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can revoke an invite',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can resend an invite',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
],
}
const BILLING_PERMISSIONS = {
title: 'Billing',
actions: [
{
description: 'Can read invoices',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can read billing email',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can change billing email',
permissions: {
owner: true,
admin: false,
developer: false,
},
},
{
description: 'Can view subscription',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can update subscription',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can read billing address',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can update billing address',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can read tax codes',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can update tax codes',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can read payment methods',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
{
description: 'Can update payment methods',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
],
}
const PROJECT_PERMISSIONS = {
title: 'Projects',
actions: [
{
description: 'Can create a project',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can delete a project',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can update a project',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can pause a project',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can resume a project',
permissions: {
owner: true,
admin: true,
developer: false,
},
},
{
description: 'Can restart a project',
permissions: {
owner: true,
admin: true,
developer: true,
},
},
],
}
export const PERMISSIONS_MAPPING = [
ORGANIZATIONS_PERMISSIONS,
MEMBERS_MANAGEMENT_PERMISSIONS,
BILLING_PERMISSIONS,
PROJECT_PERMISSIONS,
]
@@ -0,0 +1,96 @@
import { FC, Fragment, useState } from 'react'
import { IconCheck, IconHelpCircle, Modal } from '@supabase/ui'
import { PERMISSIONS_MAPPING } from './RolesHelperModal.constants'
interface Props {}
const RolesHelperModal: FC<Props> = ({}) => {
const [showModal, setShowModal] = useState(false)
return (
<>
<IconHelpCircle
size={16}
strokeWidth={1.5}
className="cursor-pointer hover:text-scale-1200 transition"
onClick={() => setShowModal(!showModal)}
/>
<Modal
closable
hideFooter
visible={showModal}
size="xlarge"
header="Permissions for each role"
onCancel={() => setShowModal(!showModal)}
>
<div className="py-4 space-y-4">
<Modal.Content>
<p className="text-sm">
The following table shows the corresponding permissions for each available role in the
dashboard.
</p>
</Modal.Content>
<Modal.Content>
<div className="bg-scale-400 border border-scale-500 rounded">
<div className="flex items-center border-b border-scale-600">
<div className="text-sm w-[49%] pl-4 font-bold">Permissions</div>
<div className="text-sm w-[17%] h-8 flex items-center justify-center border-l border-scale-600 font-bold">
Owner
</div>
<div className="text-sm w-[17%] h-8 flex items-center justify-center border-l border-scale-600 font-bold">
Adminstrator
</div>
<div className="text-sm w-[17%] h-8 flex items-center justify-center border-l border-scale-600 font-bold">
Developer
</div>
</div>
<div className="max-h-[425px] overflow-y-auto">
{PERMISSIONS_MAPPING.map((group) => (
<Fragment key={group.title}>
<div className="flex items-center py-2 px-4 border-b border-scale-600 last:border-none">
<div className="text-sm w-[100%]">{group.title}</div>
</div>
{group.actions.map((action, idx) => (
<div
key={`${group.title}-${idx}`}
className="bg-scale-500 flex items-center border-b border-scale-600 last:border-none"
>
<div className="text-sm w-[49%] pl-4">{action.description}</div>
<div
className={[
'h-8 text-center border-l border-scale-600',
'text-sm w-[17%] flex items-center justify-center',
].join(' ')}
>
{action.permissions.owner && <IconCheck size={14} strokeWidth={2} />}
</div>
<div
className={[
'h-8 text-center border-l border-scale-600',
'text-sm w-[17%] flex items-center justify-center',
].join(' ')}
>
{action.permissions.admin && <IconCheck size={14} strokeWidth={2} />}
</div>
<div
className={[
'h-8 text-center border-l border-scale-600',
'text-sm w-[17%] flex items-center justify-center',
].join(' ')}
>
{action.permissions.developer && <IconCheck size={14} strokeWidth={2} />}
</div>
</div>
))}
</Fragment>
))}
</div>
</div>
</Modal.Content>
</div>
</Modal>
</>
)
}
export default RolesHelperModal
@@ -3,7 +3,7 @@ import { useRouter } from 'next/router'
import { Button } from '@supabase/ui'
import * as Tooltip from '@radix-ui/react-tooltip'
import { useStore, checkPermissions } from 'hooks'
import { useStore, checkPermissions, useFlag } from 'hooks'
import { API_URL } from 'lib/constants'
import { delete_ } from 'lib/common/fetch'
import TextConfirmModal from 'components/ui/Modals/TextConfirmModal'
@@ -16,13 +16,17 @@ interface Props {
const DeleteProjectButton: FC<Props> = ({ type = 'danger' }) => {
const router = useRouter()
const { app, ui } = useStore()
const enablePermissions = useFlag('enablePermissions')
const project = ui.selectedProject
const isOwner = ui.selectedOrganization?.is_owner
const [isOpen, setIsOpen] = useState(false)
const [loading, setLoading] = useState(false)
const canDeleteProject = checkPermissions(PermissionAction.UPDATE, 'projects')
const canDeleteProject = enablePermissions
? checkPermissions(PermissionAction.UPDATE, 'projects')
: isOwner
const toggle = () => {
if (loading) return
@@ -52,11 +56,9 @@ const DeleteProjectButton: FC<Props> = ({ type = 'danger' }) => {
<>
<Tooltip.Root delayDuration={0}>
<Tooltip.Trigger>
<div className="flex items-center">
<Button onClick={toggle} type={type} disabled={!canDeleteProject}>
Delete project
</Button>
</div>
<Button onClick={toggle} type={type} disabled={!canDeleteProject}>
Delete project
</Button>
</Tooltip.Trigger>
{!canDeleteProject && (
<Tooltip.Content side="bottom">
@@ -23,7 +23,7 @@ const DeleteProjectPanel: FC<Props> = ({}) => {
withIcon
title="Deleting this project will also remove your database."
>
<div className="flex flex-col">
<div>
<p className="mb-4 block">
Make sure you have made a backup if you want to keep your data.
</p>
@@ -2,7 +2,7 @@ import { FC } from 'react'
import { Form, Input } from '@supabase/ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { useStore, checkPermissions } from 'hooks'
import { useStore, checkPermissions, useFlag } from 'hooks'
import { API_URL } from 'lib/constants'
import { post } from 'lib/common/fetch'
import {
@@ -20,9 +20,14 @@ const General: FC<Props> = ({}) => {
const { app, ui } = useStore()
const project = ui.selectedProject
const enablePermissions = useFlag('enablePermissions')
const isOwner = ui.selectedOrganization?.is_owner
const formId = 'project-general-settings'
const initialValues = { name: project?.name ?? '', ref: project?.ref ?? '' }
const canUpdateProject = checkPermissions(PermissionAction.UPDATE, 'projects')
const canUpdateProject = enablePermissions
? checkPermissions(PermissionAction.UPDATE, 'projects')
: isOwner
const onSubmit = async (values: any, { setSubmitting, resetForm }: any) => {
const response = await post(`${API_URL}/projects/${project?.ref}/update`, { name: values.name })
@@ -5,7 +5,7 @@ import * as Tooltip from '@radix-ui/react-tooltip'
import { Button, IconPause } from '@supabase/ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { checkPermissions, useStore } from 'hooks'
import { checkPermissions, useStore, useFlag } from 'hooks'
import { post } from 'lib/common/fetch'
import { API_URL, PROJECT_STATUS } from 'lib/constants'
import ConfirmModal from 'components/ui/Dialogs/ConfirmDialog'
@@ -21,13 +21,15 @@ const PauseProjectButton: FC<Props> = observer(({ projectRef, projectId }) => {
const [loading, setLoading] = useState(false)
const [isModalOpen, setIsModalOpen] = useState(false)
const enablePermissions = useFlag('enablePermissions')
const isOwner = ui.selectedOrganization?.is_owner
const openModal = () => setIsModalOpen(true)
const closeModal = () => setIsModalOpen(false)
const canPauseProject = checkPermissions(
PermissionAction.INFRA_EXECUTE,
'queue_jobs.projects.pause'
)
const canPauseProject = enablePermissions
? checkPermissions(PermissionAction.INFRA_EXECUTE, 'queue_jobs.projects.pause')
: isOwner
const requestPauseProject = async () => {
if (!canPauseProject) {
@@ -12,13 +12,16 @@ import DatabaseApiColumnRender from './LogColumnRenderers/DatabaseApiColumnRende
import DatabasePostgresColumnRender from './LogColumnRenderers/DatabasePostgresColumnRender'
import CSVButton from 'components/ui/CSVButton'
import DefaultPreviewColumnRenderer from './LogColumnRenderers/DefaultPreviewColumnRenderer'
import { LogQueryError } from '.'
import ResourcesExceededErrorRenderer from './LogsErrorRenderers/ResourcesExceededErrorRenderer'
import DefaultErrorRenderer from './LogsErrorRenderers/DefaultErrorRenderer'
interface Props {
data?: Array<LogData | Object>
onHistogramToggle?: () => void
isHistogramShowing?: boolean
isLoading?: boolean
error?: any
error?: LogQueryError | null
showDownload?: boolean
// TODO: move all common params to a context to avoid prop drilling
queryType?: QueryType
@@ -227,6 +230,34 @@ const LogTable = ({
}
}, [stringData])
const renderErrorAlert = () => {
if (!error) return null
const childProps = {
isCustomQuery: queryType ? false : true,
error: error!,
}
let Renderer = DefaultErrorRenderer
if (
typeof error === 'object' &&
error.error?.errors.find((err) => err.reason === 'resourcesExceeded')
) {
Renderer = ResourcesExceededErrorRenderer
}
return (
<div className="flex justify-center px-5">
<Alert
variant="danger"
title="Sorry! An error occured when fetching data."
withIcon
className="w-1/2"
>
<Renderer {...childProps} />
</Alert>
</div>
)
}
return (
<>
<section
@@ -338,27 +369,7 @@ const LogTable = ({
</>
</div>
)}
{error && (
<div className="flex justify-center px-5">
<Alert
variant="danger"
title="Sorry! An error occured when fetching data."
withIcon
className="w-1/2"
>
<Input.TextArea
size="tiny"
value={
typeof error === 'string' ? error : JSON.stringify(error, null, 2)
}
borderless
className="font-mono w-full mt-4"
copy
rows={12}
/>
</Alert>
</div>
)}
{error && renderErrorAlert()}
</div>
</>
) : null
@@ -51,9 +51,19 @@ export interface CountData {
type LFResponse<T> = {
result: T[]
error?: {
code: number
errors: {
domain: string
message: string
reason: string | 'resourcesExceeded'
}[]
message: string
status: string
}
}
type ApiError = string
export type LogQueryError = Omit<LFResponse<unknown>, "result"> | ApiError
export type Count = LFResponse<CountData>
@@ -0,0 +1,19 @@
import { Input } from '@supabase/ui'
import { LogQueryError } from '..'
export interface ErrorRendererProps {
error: LogQueryError
isCustomQuery: boolean
}
const DefaultErrorRenderer: React.FC<ErrorRendererProps> = ({ error }) => (
<Input.TextArea
size="tiny"
value={typeof error === 'string' ? error : JSON.stringify(error, null, 2)}
borderless
className="font-mono w-full mt-4"
copy
rows={7}
/>
)
export default DefaultErrorRenderer
@@ -0,0 +1,65 @@
import React, { useState } from 'react'
import DefaultErrorRenderer from './DefaultErrorRenderer'
import ResourcesExceededErrorRenderer from './ResourcesExceededErrorRenderer'
import { Alert } from '@supabase/ui'
export default {
title: 'Logs',
}
export const ErrorRenderers = () => (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '10px',
}}
>
{[
<DefaultErrorRenderer isCustomQuery={false} error="some string error" />,
<DefaultErrorRenderer
isCustomQuery={false}
error={{
error: { code: 123, errors: [], status: 'something', message: 'some logflare error' },
}}
/>,
<ResourcesExceededErrorRenderer
isCustomQuery
error={{
error: {
code: 123,
errors: [
{ domain: 'global', message: 'Some very long message', reason: 'resourcesExceeded' },
],
status: 'something',
message: 'some logflare error',
},
}}
/>,
<ResourcesExceededErrorRenderer
isCustomQuery={false}
error={{
error: {
code: 123,
errors: [
{ domain: 'global', message: 'Some very long message', reason: 'resourcesExceeded' },
],
status: 'something',
message: 'some logflare error',
},
}}
/>,
].map((child) => (
<Alert
variant="danger"
title="Sorry! An error occured when fetching data."
withIcon
className="w-1/2"
>
{child}
</Alert>
))}
</div>
)
@@ -0,0 +1,39 @@
import { Accordion, Input } from '@supabase/ui'
import { ErrorRendererProps } from './DefaultErrorRenderer'
const ResourcesExceededErrorRenderer: React.FC<ErrorRendererProps> = ({ error, isCustomQuery }) => (
<div className="text-scale-1100 flex flex-col gap-2">
<div className="text-sm flex flex-col gap-1">
<p>This query requires too much memory to be executed.</p>
<p>
{isCustomQuery
? 'Avoid selecting entire objects and instead select specific keys using dot notation.'
: 'Avoid querying across a large datetime range.'}
</p>
{!isCustomQuery && <p>Please contact support if this error persists.</p>}
</div>
<Accordion
className="text-sm"
justified={false}
openBehaviour="multiple"
type="default"
chevronAlign="left"
size="small"
bordered={false}
iconPosition="left"
>
<Accordion.Item id="1" header="Full error message">
<Input.TextArea
size="tiny"
value={JSON.stringify(error, null, 2)}
borderless
className="font-mono w-full mt-4"
copy
rows={5}
/>
</Accordion.Item>
</Accordion>
</div>
)
export default ResourcesExceededErrorRenderer
@@ -36,7 +36,7 @@ export const generateAuthMenu = (ref: string): ProductMenuGroup[] => {
]
: []),
{
name: 'Templates',
name: 'Email Templates',
key: 'templates',
url: `/project/${ref}/auth/templates`,
items: [],
@@ -5,6 +5,7 @@ import {
IconMessageCircle,
Popover,
IconBookOpen,
IconActivity,
} from '@supabase/ui'
import { useRouter } from 'next/router'
import { FC } from 'react'
@@ -34,20 +35,21 @@ const HelpPopover: FC<Props> = () => {
For issues with your project hosted on supabase.com, or other inquiries about our
hosted services.
</p>
<div className="space-x-2">
<Link href={supportUrl}>
<a>
<Button type="default" icon={<IconMail />}>
Contact support team
</Button>
</a>
<div className="space-x-1">
<Link passHref href={supportUrl}>
<Button type="default" icon={<IconMail />} as="a">
Contact Support
</Button>
</Link>
<Link href="https://supabase.com/docs/">
<a>
<Button type="secondary" size="tiny" icon={<IconBookOpen />}>
Docs
</Button>
</a>
<Link passHref href="https://supabase.com/docs/">
<Button type="text" size="tiny" icon={<IconBookOpen />} as="a">
Docs
</Button>
</Link>
<Link passHref href="https://status.supabase.com/">
<Button type="text" size="tiny" icon={<IconActivity />} as="a">
Supabase Status
</Button>
</Link>
</div>
<p className="text-sm text-scale-900">
@@ -4,7 +4,7 @@ import { Alert, Button, IconPauseCircle } from '@supabase/ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { Project } from 'types'
import { checkPermissions, useStore, useSubscriptionStats } from 'hooks'
import { checkPermissions, useStore, useSubscriptionStats, useFlag } from 'hooks'
import { post } from 'lib/common/fetch'
import { API_URL, PROJECT_STATUS, DEFAULT_FREE_PROJECTS_LIMIT } from 'lib/constants'
import { DeleteProjectButton } from 'components/interfaces/Settings/General'
@@ -20,13 +20,15 @@ const ProjectPausedState: FC<Props> = ({ project }) => {
const { total_active_free_projects: totalActiveFreeProjects } = subscriptionStats
const freeProjectsLimit = ui.profile?.free_project_limit ?? DEFAULT_FREE_PROJECTS_LIMIT
const enablePermissions = useFlag('enablePermissions')
const isOwner = ui.selectedOrganization?.is_owner
const [showConfirmRestore, setShowConfirmRestore] = useState(false)
const hasExceedActiveFreeProjectsLimit = totalActiveFreeProjects >= freeProjectsLimit
const canResumeProject = checkPermissions(
PermissionAction.INFRA_EXECUTE,
'queue_jobs.projects.initialize_or_resume'
)
const canResumeProject = enablePermissions
? checkPermissions(PermissionAction.INFRA_EXECUTE, 'queue_jobs.projects.initialize_or_resume')
: isOwner
const onSelectRestore = () => {
if (!canResumeProject) {
+1 -1
View File
@@ -48,7 +48,7 @@ const Th: React.FC<ThProps> = ({ children, className, style }) => {
if (className) classes.push(className)
return (
<th className={classes.join(' ')} style={style}>
<Typography.Text type="secondary">{children}</Typography.Text>
{children}
</th>
)
}
+1 -1
View File
@@ -118,7 +118,7 @@
}
.table-container thead th {
@apply text-scale-900 font-normal text-sm;
@apply text-scale-1100 font-normal text-sm;
@apply bg-table-header-light dark:bg-table-header-dark;
@apply border-t border-b border-table-border-light dark:border-table-border-dark;
}
@@ -90,3 +90,37 @@ test('error message handling', async () => {
await screen.findByText(/string/)
await screen.findByText(/my_error/)
})
test('custom error message: Resources exceeded during query execution', async () => {
const errorFromLogflare = {
error: {
code: 400,
errors: [
{
domain: 'global',
message:
'Resources exceeded during query execution: The query could not be executed in the allotted memory. Peak usage: 122% of limit.\nTop memory consumer(s):\n ORDER BY operations: 99%\n other/unattributed: 1%\n',
reason: 'resourcesExceeded',
},
],
message:
'Resources exceeded during query execution: The query could not be executed in the allotted memory. Peak usage: 122% of limit.\nTop memory consumer(s):\n ORDER BY operations: 99%\n other/unattributed: 1%\n',
status: 'INVALID_ARGUMENT',
},
}
// logs explorer, custom query
const { rerender } = render(<LogTable error={errorFromLogflare} />)
// prompt user to reduce selected tables
await screen.findByText(/This query requires too much memory to be executed/)
await screen.findByText(
/Avoid selecting entire objects and instead select specific keys using dot notation/
)
// previewer, prompt to reduce time range
rerender(<LogTable queryType="api" error={errorFromLogflare} />)
await screen.findByText(/This query requires too much memory to be executed/)
await screen.findByText(/Avoid querying across a large datetime range/)
await screen.findByText(/Please contact support if this error persists/)
})
+74 -101
View File
@@ -2,6 +2,7 @@
id: api
title: APIs
description: Auto-generating and Realtime APIs.
sidebar_label: Overview
---
import Tabs from '@theme/Tabs';
@@ -24,7 +25,7 @@ The APIs are:
- **Scalable.** <br />The API can serve thousands of simultaneous requests, and works well for Serverless workloads.
### REST API
### REST API {#rest-api-overview}
Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres.
It provides everything you need from a CRUD API:
@@ -45,7 +46,7 @@ It provides everything you need from a CRUD API:
allowFullScreen
></iframe>
### GraphQL API
### GraphQL API {#graphql-api-overview}
:::note
@@ -55,7 +56,7 @@ GraphQL is in Beta, and may have breaking changes. It is only available on self-
GraphQL in Supabase works through [pg_graphql](https://supabase.com/blog/2021/12/03/pg-graphql), an open source PostgreSQL extension for GraphQL.
### Realtime API
### Realtime API {#realtime-api-overview}
Supabase provides a Realtime API using [Realtime](https://github.com/supabase/realtime). You can use this to listen to database changes over websockets.
Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications.
@@ -69,33 +70,31 @@ All APIs are auto-created from Database tables. After you have added tables or f
API routes are automatically created when you create Postgres Tables, Views, or Functions.
Let's create our first
API route by creating a table called `todos` (which will store some public user information).
This will create a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests.
API route by creating a table called `todos` to store tasks.
This creates a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Table editor" section.
2. Click "New Table".
3. Enter the table name "todos".
4. Click "Save".
5. Click "New Column".
6. Enter the column name "task" and make the type "text".
7. Click "Save".
```
<TabItem value="dashboard">
1. Go to the [Table editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
1. Click **New Table** and create a table with the name `todos`.
1. Click **Save**.
1. Click **New Column** and create a column with the name `task` and type `text`.
1. Click **Save**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table called "todos" with a column to store tasks.
@@ -113,13 +112,9 @@ create table todos (
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings/general) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
@@ -134,42 +129,27 @@ Both of these routes require the `anon` key to be passed through an `apikey` hea
#### API Keys
You can find the Keys inside the Dashboard in the same location as the URL above.
You are provided with two keys:
- an `anon` key, which is safe to be used in a browser context.
- a `service_role` key, which should only be used on a server. This key can bypass Row Level Security. NEVER use this key in a browser.
### Accessing the Docs
### Accessing the docs in the Dashboard
#### REST API
#### REST API {#rest-api-dashboard-docs}
Supabase generates documentation in the Dashboard which updates as you make database changes.
Supabase generates documentation in the [Dashboard](https://app.supabase.com) which updates as you make database changes.
Let's view the documentation for a `countries` table which we created in our database.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "API" section.
2. Find "todos" in the "Tables and Views" section.
1. Go to the [API](https://app.supabase.com/project/_/api) page in the Dashboard.
2. Find the `countries` table under **Tables and Views** in the sidebar.
3. Switch between the JavaScript and the cURL docs using the tabs.
```
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-docs.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
#### GraphQL
The GraphQL Endpoint that we provide (`https://<project_ref>.supabase.co/graphql/v1`) is compatible with any GraphiQL implementation that can pass an `apikey` header.
@@ -192,12 +172,14 @@ using the API URL (`SUPABASE_URL`) and Key (`SUPABASE_ANON_KEY`) we provided:
<Tabs
defaultValue="JavaScript"
values={[
{label: 'JavaScript', value: 'JavaScript'},
{label: 'cURL', value: 'cURL'},
]}>
<TabItem value="JavaScript">
groupId="language"
defaultValue="javascript"
values={[
{label: 'JavaScript', value: 'javascript'},
{label: 'cURL', value: 'curl'},
]}>
<TabItem value="javascript">
```javascript
// Initialize the JS client
@@ -211,7 +193,7 @@ const { data: todos, error } = await supabase
```
</TabItem>
<TabItem value="cURL">
<TabItem value="curl">
```bash
# Append /rest/v1/ to your URL, and then use the table name as the route
@@ -243,12 +225,14 @@ Be sure to rebuild the GraphQL schema after altering the SQL schema.
You can use any GraphQL client with the Supabase GraphQL API. For our GraphQL example we will use [urql](https://formidable.com/open-source/urql/docs/).
<Tabs
defaultValue="Javascript"
values={[
{label: 'Javascript', value: 'Javascript'},
{label: 'cURL', value: 'cURL'},
]}>
<TabItem value="Javascript">
groupId="language"
defaultValue="javascript"
values={[
{label: 'JavaScript', value: 'javascript'},
{label: 'cURL', value: 'curl'},
]}>
<TabItem value="javascript">
```javascript
import { createClient, useQuery } from 'urql'
@@ -292,7 +276,7 @@ const { data, fetching, error } = result
```
</TabItem>
<TabItem value="cURL">
<TabItem value="curl">
```bash
# Append /graphql/v1/ to your URL, and then use the table name as the route
@@ -311,26 +295,26 @@ curl --request POST '<SUPABASE_URL>/graphql/v1' \
By default Realtime is disabled on your database. Let's turn on Realtime for the `todos` table.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Database" section.
2. Click on "Replication" in the sidebar.
3. Control which database events are sent by toggling the Insert/Update/Delete toggles.
4. Control which tables broadcast changes by clicking into the "Source" and toggling the tables.
```
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Replication** in the sidebar.
3. Control which database events are sent by toggling **Insert**, **Update**, and **Delete**.
4. Control which tables broadcast changes by selecting **Source** and toggling each table.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
alter publication supabase_realtime add table todos;
@@ -339,14 +323,7 @@ alter publication supabase_realtime add table todos;
</TabItem>
</Tabs>
Now we can listen to any new data that is inserted into the `todos` table:
<Tabs
defaultValue="Javascript"
values={[
{label: 'Javascript', value: 'Javascript'}
]}>
<TabItem value="Javascript">
From the client, we can listen to any new data that is inserted into the `todos` table:
```javascript
// Initialize the JS client
@@ -365,9 +342,6 @@ const { data: todos, error } = await supabase
.subscribe()
```
</TabItem>
</Tabs>
Use [subscribe()](/docs/reference/javascript/subscribe) to listen to database changes.
The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a [publication](/docs/guides/database/replication#publications)
called `supabase_realtime`, and by managing this publication you can control which data is broadcast.
@@ -378,26 +352,26 @@ called `supabase_realtime`, and by managing this publication you can control whi
### Securing your Routes
Your API is designed to work with Postgres Row Level Security. If you use Supabase [Auth](/docs/guides/auth), you can restrict data based on the logged-in user.
Your API is designed to work with Postgres Row Level Security (RLS). If you use Supabase [Auth](/docs/guides/auth), you can restrict data based on the logged-in user.
To control access to your data, you can use [Policies](/docs/guides/auth#policies).
When you create a table in Postgres, Row Level Security is disabled by default. Make sure you secure it by [enabling RLS](/docs/guides/api#securing-your-routes).
When you create a table in Postgres, Row Level Security is disabled by default. To enable RLS:
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the "Authentication" section.
2. Click on "Policies" in the sidebar.
3. Click "Enable RLS" to enable Row Level Security.
```
<TabItem value="dashboard">
1. Go to the [Authentication](https://app.supabase.com/project/_/auth/users) page in the Dashboard.
2. Click on **Policies** in the sidebar.
3. Select **Enable RLS** to enable Row Level Security.
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
alter table todos enable row level security;
@@ -408,7 +382,6 @@ alter table todos enable row level security;
### The `service_role` key
Never expose the `service_role` key in a browser or anywhere where a user can see it. This Key can is designed to bypass Row Level Security - so it should only be used on a private server.
We have [partnered with GitHub](https://supabase.com/blog/2022/03/28/community-day#supabase-is-now-a-github-secret-scanning-partner) to scan for Supabase `service_role` keys pushed to public repositories.
+1
View File
@@ -2,6 +2,7 @@
id: auth
title: Auth
description: Use Supabase to Authenticate and Authorize your users.
sidebar_label: Overview
---
import Link from '@docusaurus/Link'
+1
View File
@@ -2,6 +2,7 @@
id: database
title: Database
description: Use Supabase to manage your data.
sidebar_label: Overview
---
Every Supabase project comes with a full [Postgres](https://www.postgresql.org/) database, a free and open source
+55 -65
View File
@@ -7,38 +7,31 @@ description: How to use arrays in PostgreSQL and the Supabase API.
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
PostgreSQL supports flexible [array types](https://www.postgresql.org/docs/12/arrays.html).
These arrays are also supported in the Supabase dashboard and in the JavaScript API.
PostgreSQL supports flexible [array types](https://www.postgresql.org/docs/12/arrays.html). These arrays are also supported in the Supabase Dashboard and in the JavaScript API.
## Steps
### Create a table with an array column
## Create a table with an array column
Create a test table with a text array (an array of strings):
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="UI">
<TabItem value="dashboard">
```bash
1. Got the Table Editor
2. Create a New Table
3. Create a new table named `arraytest` and save the table
- New Column
- Name the new column `textarray`
- Make it type `text`
- Check the box labelled `Define as array`
- Save the new column
```
1. Go to the [Table editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
1. Click **New Table** and create a table with the name `arraytest`.
1. Click **Save**.
1. Click **New Column** and create a column with the name `textarray`, type `text`, and select **Define as array**.
1. Click **Save**.
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
CREATE TABLE arraytest (id integer NOT NULL, textarray text ARRAY);
@@ -47,30 +40,27 @@ CREATE TABLE arraytest (id integer NOT NULL, textarray text ARRAY);
</TabItem>
</Tabs>
### Insert a record with an array value
## Insert a record with an array value
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
]}>
<TabItem value="UI">
<TabItem value="dashboard">
```bash
- Table Editor
- Select `arraytest`
- Insert Row
- In the `textarray` field input, paste:
- `["Harry", "Larry", "Moe"]`
- Save the new row
```
1. Go to the [Table editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
1. Select the `arraytest` table.
1. Click **Insert row** and add `["Harry", "Larry", "Moe"]`.
1. Click **Save.**
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
INSERT INTO arraytest (id, textarray) VALUES (1, ARRAY['Harry', 'Larry', 'Moe']);
@@ -78,8 +68,8 @@ INSERT INTO arraytest (id, textarray) VALUES (1, ARRAY['Harry', 'Larry', 'Moe'])
</TabItem>
<TabItem value="JavaScript">
To insert a record from the JavaScript client:
<TabItem value="javascript">
Insert a record from the JavaScript client:
```js
const { data, error } = await supabase
@@ -91,36 +81,35 @@ const { data, error } = await supabase
</Tabs>
### View the results
## View the results
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="UI">
<TabItem value="dashboard">
```bash
- Table Editor
- Select `arraytest`
```
1. Go to the [Table editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
1. Select the `arraytest` table.
Your first array data!
You should see:
| id | textarray |
| --- | ----------------------- |
| 1 | ["Harry","Larry","Moe"] |
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
SELECT * FROM arraytest;
```
Your first array data!
You should see:
| id | textarray |
| --- | ----------------------- |
@@ -129,18 +118,19 @@ Your first array data!
</TabItem>
</Tabs>
### Query Array Data
## Query array data
To query an array, PostgreSQL uses 1-based arrays, so be careful, since you're probably used to 0-based arrays in JavaScript.
PostgreSQL uses 1-based indexing (e.g., `textarray[1]` is the first item in the array).
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
groupId="dashboard-or-sql"
defaultValue="sql"
values={[
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
]}>
<TabItem value="SQL">
<TabItem value="sql">
To select the first item from the array and get the total length of the array:
@@ -155,7 +145,8 @@ returns:
| Harry | 3 |
</TabItem>
<TabItem value="JavaScript">
<TabItem value="javascript">
This returns the entire array field:
@@ -175,7 +166,6 @@ returns:
```
</TabItem>
</Tabs>
## Resources
@@ -1,6 +1,6 @@
---
id: connecting-to-postgres
title: 'Connecting'
title: 'Database Connections'
description: There are various ways to connect to your Postgres database.
---
@@ -38,30 +38,14 @@ We provides several types of API to suit your preferences and use-case:
You cannot manage the database schema via the API (for security reasons). To do that you can use the dashboard or connect directly to your database.
### Finding your API URL
### API URL and Keys
You can find the API URL and Keys inside the Dashboard.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL and Keys in this page.
```
You can find the API URL and Keys in the [Dashboard](https://app.supabase.com/project/_/settings/api).
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Direct connections
Every Supabase project provides a full Postgres database. You can connect to the database using any tool which supports Postgres.
+16 -22
View File
@@ -14,47 +14,41 @@ Supabase has pre-installed some of the most useful open source extensions.
### Enable and disable extensions
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the Database page
2. Click on "Extensions" in the sidebar
3. Find the extension you would like to enable/disable
4. Click the toggle.
```
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click **Extensions** in the sidebar.
3. Enable or disable an extension.
<video width="99%" muted playsInline controls={true}>
<source src="/docs/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
```sql
<TabItem value="sql">
```sql
-- Example: enable the "pgtap" extension and ensure it is installed
create extension pgtap with schema extensions;
-- Example: disable the "pgtap" extension
drop extension pgtap;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
To disable an extension call `drop extension`.
Enabling few extensions by the SQL code `create extension <extension-name> with schema extensions` may lead to permission issues (e.g. `dblink`, `http`, `pg_cron`).
:::caution
Enabling some extensions with `create extension <extension-name> with schema extensions` may lead to permission issues (e.g., `dblink`, `http`, `pg_cron`).
:::
</TabItem>
@@ -63,6 +57,6 @@ Enabling few extensions by the SQL code `create extension <extension-name> with
### Full list of extensions
Supabase is pre-configured with over 50 extensions. You can also install your own SQL extensions directly into the database through our SQL editor.
Supabase is pre-configured with over 50 extensions. You can also install your own SQL extensions directly in the database through our SQL editor.
<ExtensionsComponent />
+14 -20
View File
@@ -37,40 +37,34 @@ You can use the `http` extension to make these network requests from Postgres.
## Usage
### Enabling
### Enable the extension
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
```sh
1. Go to the Database page.
2. Click on "Extensions" in the sidebar.
3. Search for "http".
4. Click the toggle.
```
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "http" and enable the extension.
</TabItem>
<TabItem value="SQL">
```sql
<TabItem value="sql">
```sql
-- Example: enable the "http" extension
create extension http with schema extensions;
-- Example: disable the "http" extension
drop extension if exists http;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
To disable an extension, call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
@@ -125,4 +119,4 @@ from
## Resources
- Official [`http` GitHub Repository](https://github.com/pramsey/pgsql-http).
- Official [`http` GitHub Repository](https://github.com/pramsey/pgsql-http)
+14 -21
View File
@@ -16,43 +16,36 @@ Let's cover some basic concepts:
- Unit tests: allow you to test small parts of a system (like a database table!).
- TAP: stands for [Test Anything Protocol](http://testanything.org/). It is an framework which aims to simplify the error reporting during testing.
## Usage
### Enabling
### Enable the extension
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the Database page.
2. Click on "Extensions" in the sidebar.
3. Search for "pgtap".
4. Click the toggle.
```
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pgtap" and enable the extension.
<video width="99%" muted playsInline controls={true}>
<source src="/docs/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
```sql
<TabItem value="sql">
```sql
-- Enable the "pgtap" extension
create extension pgtap with schema extensions;
-- Disable the "pgtap" extension
drop extension if exists pgtap;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
@@ -130,4 +123,4 @@ API:
## Resources
- Official [`pgTAP` documentation](https://pgtap.org/).
- Official [`pgTAP` documentation](https://pgtap.org/)
+27 -38
View File
@@ -18,47 +18,41 @@ It can be used for database functions, triggers, queries and more.
## Usage
### Enabling
### Enable the extension
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
```sh
1. Go to the Database page.
2. Click on "Extensions" in the sidebar.
3. Search for "plv8".
4. Click the toggle.
```
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "plv8" and enable the extension.
</TabItem>
<TabItem value="SQL">
```sql
<TabItem value="sql">
```sql
-- Example: enable the "plv8" extension
create extension plv8;
-- Example: disable the "plv8" extension
drop extension if exists plv8;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
To disable an extension, call `drop extension`.
Procedural languages are automatically installed within `pg_catalog`, so you don't need to specify a schema.
</TabItem>
</Tabs>
### Creating `plv8` functions
### Create `plv8` functions
Functions written in `plv8` are written just like any other PostgreSQL functions, only
with the `language` identifier set to `plv8`.
@@ -74,28 +68,24 @@ $$ language plv8;
You can call `plv8` functions like any other Postgres function:
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JavaScript', value: 'JS'},
]}>
<TabItem value="SQL">
defaultValue="sql"
values={[
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
]}>
<TabItem value="sql">
```sql
select function_name();
```
</TabItem>
<TabItem value="JS">
```js
<TabItem value="javascript">
```js
const { data, error } = supabase.rpc('function_name')
```
</TabItem>
@@ -103,7 +93,7 @@ const { data, error } = supabase.rpc('function_name')
## Examples
### Scalar Functions
### Scalar functions
A [scalar function](https://plv8.github.io/#scalar-function-calls) is anything that takes in some user input and returns a single result.
@@ -134,7 +124,7 @@ returns smallint as $$
$$ language plv8;
```
### Set-returning Functions
### Set-returning functions
A [set-returning function](https://plv8.github.io/#set-returning-function-calls) is anything that returns a full set of results - for example, rows in a table.
@@ -150,8 +140,7 @@ returns setof messages as $$
$$ language plv8;
```
## Resources
- Official [`plv8` documentation](https://plv8.github.io/).
- [plv8 GitHub Repository](https://github.com/plv8/plv8).
- Official [`plv8` documentation](https://plv8.github.io/)
- [plv8 GitHub Repository](https://github.com/plv8/plv8)
@@ -17,40 +17,37 @@ This makes them particularly well suited as Primary Keys. It is occasionally ref
## Usage
### Enabling
### Enable the extension
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "uuid-ossp" and enable the extension.
```sh
1. Go to the Database page.
2. Click on "Extensions" in the sidebar.
3. Search for "uuid-ossp".
4. Click the toggle.
```
**Note**:
Currently `uuid-ossp` extension is enabled by default and cannot be disabled.
</TabItem>
<TabItem value="SQL">
```sql
<TabItem value="sql">
```sql
-- Example: enable the "uuid-ossp" extension
create extension "uuid-ossp" with schema extensions;
-- Example: disable the "uuid-ossp" extension
drop extension if exists "uuid-ossp";
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
To disable an extension, call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
@@ -98,4 +95,4 @@ create table contacts (
## Resources
- [The Basics Of PostgreSQL `UUID` Data Type](https://www.postgresqltutorial.com/postgresql-uuid/).
- [The Basics Of PostgreSQL `UUID` Data Type](https://www.postgresqltutorial.com/postgresql-uuid/)
+81 -115
View File
@@ -10,21 +10,42 @@ import TabItem from '@theme/TabItem'
PostgreSQL supports [JSON functions and operators](https://www.postgresql.org/docs/current/functions-json.html) which gives flexibility when storing data inside a database column.
PostgreSQL supports two types of JSON columns: `JSON` and `JSONB`.
The recommended type is `JSONB` for almost all cases.
When you use the `JSONB` format, the data is parsed when it's put into the database so it's faster when querying and also it can be indexed.
## Steps
### Create a table with a JSON column.
## Create a table with a JSON column
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'UI', value: 'UI'},
]}>
<TabItem value="SQL">
groupId="json"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
1. Go to the [Table Editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
2. Click **New Table** and create a table called `books`.
3. Include a primary key with the following properties:
- Name: `id`
- Type: `int8`
- Default value: `Automatically generate as indentity`
4. Click **Save**.
5. Click **New Column** and add 3 columns with the following properties:
- **title** column
- Name: `title`
- Type: `text`
- **author** column
- Name: `author`
- Type: `text`
- **metadata** column
- Name: `metadata`
- Type: `jsonb`
</TabItem>
<TabItem value="sql">
```sql
create table books (
@@ -35,51 +56,25 @@ create table books (
);
```
</TabItem>
<TabItem value="UI">
```sh
Create the table:
1. Go to the Table Editor
2. Click "New Table"
3. Name the table "books"
4. Include a primary key with the following properties:
- Name: "id"
- Type: "int8"
- Default value: "Automatically generate as indentity"
5. Click "Save"
Click "New Column" and 3 new columns with the following properties:
1. title column:
- Name: "title"
- Type: "text"
2. author column:
- Name: "author"
- Type: "text"
3. metadata column:
- Name: "metadata"
- Type: "jsonb"
```
</TabItem>
</Tabs>
### Insert data into the table.
## Insert data into the table
<Tabs
defaultValue="Data"
values={[
{label: 'Data', value: 'Data'},
{label: 'SQL', value: 'SQL'},
{label: 'UI', value: 'UI'},
{label: 'JS', value: 'JavaScript'},
]}>
<TabItem value="Data">
groupId="json"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
]}>
<TabItem value="dashboard">
1. Go to the [Table Editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
2. Select the `books` table in the sidebar.
3. Click **+ Insert row** and add 5 rows with the following properties:
| id | title | author | metadata |
| --- | ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
@@ -90,7 +85,8 @@ values={[
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} |
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
insert into books
@@ -124,40 +120,8 @@ values
```
</TabItem>
<TabItem value="UI">
```bash
- click `Table Editor`
- click `books`
- click `+ Insert Row`
- `title`: `The Poky Little Puppy`
- `author`: 'Janette Sebring Lowrey'
- `metadata`: {"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]}
- click `Save`
- click `+ Insert Row`
- `title`: `The Tale of Peter Rabbit`
- `author`: 'Beatrix Potter'
- `metadata`: {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."}
- click `Save`
- click `+ Insert Row`
- `title`: `Tootle`
- `author`: 'Gertrude Crampton'
- `metadata`: {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."}
- click `Save`
- click `+ Insert Row`
- `title`: `Green Eggs and Ham`
- `author`: 'Dr. Seuss'
- `metadata`: {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."}
- click `Save`
- click `+ Insert Row`
- `title`: `Harry Potter and the Goblet of Fire`
- `author`: 'J.K. Rowling'
- `metadata`: {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."}
- click `Save`
```
</TabItem>
<TabItem value="JavaScript">
<TabItem value="javascript">
```js
const { data, error } = await supabase.from('books').insert([
@@ -204,16 +168,18 @@ const { data, error } = await supabase.from('books').insert([
</TabItem>
</Tabs>
### View the data.
## View the data
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
{label: 'Data', value: 'Data'},
]}>
<TabItem value="SQL">
groupId="json"
defaultValue="sql"
values={[
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Result', value: 'result'},
]}>
<TabItem value="sql">
```sql
select *
@@ -221,7 +187,8 @@ from books;
```
</TabItem>
<TabItem value="JavaScript">
<TabItem value="javascript">
```js
const { data, error } = await supabase.from('books').select('*')
@@ -229,7 +196,8 @@ console.log(JSON.stringify(data, null, 2))
```
</TabItem>
<TabItem value="Data">
<TabItem value="result">
| id | title | author | metadata |
| --- | ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
@@ -239,26 +207,25 @@ console.log(JSON.stringify(data, null, 2))
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."} |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} |
NOTICE: The data as it appears here will have the `JSONB` fields in a different order than when we inserted them.
As we said earlier about the differences between the `JSON` and `JSONB` fields:
> When you use the `JSONB` format, the data is parsed when it's put into the database...
The data as it appears here has the `JSONB` fields in a different order than when inserted. As mentioned earlier, data is parsed as its inserted when using the JSONB format.
</TabItem>
</Tabs>
### Query the `JSONB` data.
## Query the `JSONB` data
#### Select title, description, price, and age range for each book.
Select the title, description, price, and age range for each book.
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
{label: 'Results', value: 'Results'}
]}>
<TabItem value="SQL">
groupId="json"
defaultValue="sql"
values={[
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Result', value: 'result'}
]}>
<TabItem value="sql">
```sql
select
@@ -272,7 +239,8 @@ from
```
</TabItem>
<TabItem value="JavaScript">
<TabItem value="javascript">
```js
const { data, error } = await supabase
@@ -284,7 +252,8 @@ console.log(JSON.stringify(data, null, 2))
```
</TabItem>
<TabItem value="Results">
<TabItem value="result">
| title | description | price | low_age | high_age |
| ----------------------------------- | ------------------------------------------------------------------ | ----- | ------- | -------- |
@@ -297,16 +266,13 @@ console.log(JSON.stringify(data, null, 2))
</TabItem>
</Tabs>
#### Data Types
Note that the `->` operator returns JSONB data. If you want TEXT/STRING data returned, use the `->>` operator.
One last thing to note: the -> operator returns JSONB data. If you want TEXT/STRING data returned, you need to use the ->> operator.
- metadata -> 'description' (this returns a JSON object)
- metadata ->> 'description' (this returns STRING/TEXT data)
- metadata -> 'description' (returns a JSON object)
- metadata ->> 'description' (returns STRING/TEXT data)
## Resources
- [Supabase Account - Free Tier OK](https://supabase.com)
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [PostgreSQL: JSON Functions and Operators](https://www.postgresql.org/docs/12/functions-json.html)
- [PostgreSQL JSON types](https://www.postgresql.org/docs/12/datatype-json.html)
+18 -156
View File
@@ -8,126 +8,48 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Replication is technique for copying the data from one database to another. This is useful for:
Replication is a technique for copying the data from one database to another. Supabase uses replication functionality to provide a real-time API. Replication is useful for:
- Spreading out the "load". For example, if your database has a lot of reads, you might want to split it between two databases.
- Spreading out the "load." For example, if your database has a lot of reads, you might want to split it between two databases.
- Reducing latency. For example, you may want one database in London to serve your European customers, and one in New York to serve the US.
- In Supabase's case, we use the built-in replication functionality to provide a real-time API.
Replication is done through _publications_, a method of choosing which changes to send to other systems (usually another Postgres database). Publications can be managed in the [Dashboard](https://app.supabase.com) or with SQL.
## Manage publications in the Dashboard
## Publications
Publications are a way of choosing which changes should be sent to other systems (usually another Postgres database).
### Managing Publications
Supabase provides an interface for managing your publications, or you can use SQL.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
```sh
1. Go to the "Database" section.
2. Click on "Replication" in the sidebar.
3. Control which database events are sent by toggling the Insert/Update/Delete toggles.
4. Control which tables broadcast changes by clicking into the "Source" and toggling the tables.
```
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Replication** in the sidebar.
3. Control which database events are sent by toggling **Insert**, **Update**, and **Delete**.
4. Control which tables broadcast changes by selecting **Source** and toggling each table.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
## Create a publication
```sql
alter publication supabase_realtime add table products;
```
</TabItem>
</Tabs>
### Create a Publication
This publication will contain all changes to all tables.
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
This publication contains changes to all tables.
```sql
create publication publication_name
for all tables;
```
</TabItem>
</Tabs>
### Create a Publication which listens to individual tables
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Create a publication to listen to individual tables
```sql
create publication publication_name
for table table_one, table_two;
```
</TabItem>
</Tabs>
### Add tables to an existing publication
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Add tables to an existing publication
```sql
alter publication publication_name
add table table_name;
```
</TabItem>
</Tabs>
### Listen to `insert`
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Listen to `insert`
```sql
create publication publication_name
@@ -135,21 +57,7 @@ for all tables
with (publish = 'insert');
```
</TabItem>
</Tabs>
### Listen to `update`
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Listen to `update`
```sql
create publication publication_name
@@ -157,21 +65,7 @@ for all tables
with (publish = 'update');
```
</TabItem>
</Tabs>
### Listen to `delete`
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Listen to `delete`
```sql
create publication publication_name
@@ -179,42 +73,15 @@ for all tables
with (publish = 'delete');
```
</TabItem>
</Tabs>
### Remove a Publication
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
## Remove a publication
```sql
drop publication if exists publication_name;
```
## Recreate a publication
</TabItem>
</Tabs>
### Recreate a Publication
If you are planning to re-create a publication, it's best to do it in a transaction to ensure the operation succeeds.
<Tabs
defaultValue="sql"
groupId="reference/postgres"
values={[{ label: 'SQL', value: 'sql' }]}>
<TabItem value="sql">
If you're recreating a publication, it's best to do it in a transaction to ensure the operation succeeds.
```sql
begin;
@@ -225,8 +92,3 @@ begin;
create publication publication_name;
commit;
```
</TabItem>
</Tabs>
+51 -45
View File
@@ -34,29 +34,27 @@ We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/
and run the SQL queries yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'Dashboard', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
</video>
```sh
1. Go to the "Table editor" section.
2. Click "New Table".
3. Enter the table name "todos".
4. Click "Save".
5. Click "New Column".
6. Enter the column name "task" and make the type "text".
7. Click "Save".
```
1. Go to the [Table Editor](https://app.supabase.com/project/_/editor) page in the Dashboard.
2. Click **New Table** and create a table with the name `todos`.
3. Click **Save**.
4. Click **New Column** and create a column with the name `task` and type `text`.
5. Click **Save**.
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
create table movies (
@@ -69,7 +67,9 @@ create table movies (
</TabItem>
</Tabs>
It is best practice to use lowercase and underscores when naming tables. For example: `table_name`, not `Table Name`.
:::note
When naming tables, use lowercase and underscores instead of spaces (e.g., `table_name`, not `Table Name`).
:::
## Columns
@@ -173,13 +173,14 @@ Use the "Bulk Loading" instructions if you are loading large data sets.
### Basic data loading
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JavaScript', value: 'JS'},
{label: 'Dart', value: 'DART'},
]}>
<TabItem value="SQL">
defaultValue="sql"
values={[
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="sql">
```sql
insert into movies
@@ -190,7 +191,8 @@ values
```
</TabItem>
<TabItem value="JS">
<TabItem value="javascript">
```sql
const { data, error } = await supabase
@@ -205,7 +207,8 @@ const { data, error } = await supabase
```
</TabItem>
<TabItem value="DART">
<TabItem value="dart">
```sql
final res = await supabase
@@ -270,12 +273,28 @@ For example if you had the following situations:
- An `actor` can perfom in several movies.
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'Dashboard', value: 'UI'},
]}>
<TabItem value="SQL">
groupId="dashboard-or-sql"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
<iframe
className="video-with-border w-full"
width="640"
height="420"
src="https://www.youtube-nocookie.com/embed/TKwF3IGij5c"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</TabItem>
<TabItem value="sql">
```sql
create table movies (
@@ -296,19 +315,6 @@ create table performances (
);
```
</TabItem>
<TabItem value="UI">
<iframe
className="video-with-border w-full"
width="640"
height="420"
src="https://www.youtube-nocookie.com/embed/TKwF3IGij5c"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</TabItem>
</Tabs>
+3 -2
View File
@@ -1,7 +1,8 @@
---
id: docker
title: With Docker
description: How to use configure and deploy Supabase.
title: Self-hosting with Docker
description: How to configure and deploy Supabase.
sidebar_label: Docker
---
Docker is the easiest way to get started with self-hosted Supabase.
+1 -2
View File
@@ -61,8 +61,7 @@ In order to query any value that is an array, we would need to `UNNEST()` that f
:::caution
Large projects may run into a `400 ORDER BY` memory limit error when querying with many unnested rows across large date ranges. If experiencing this error, consider reducing the number of unnested joins, or by reducing the queried date range.
Large projects may run into a `Resources Exceeded` memory limit error when selecting large objects with many nested keys. To avoid this error, select individual keys separately or reduce the queried date range.
:::
### Functions
+55 -59
View File
@@ -2,6 +2,7 @@
id: storage
title: Storage
description: Use Supabase to store and serve files.
sidebar_label: Overview
---
import Tabs from '@theme/Tabs'
@@ -44,28 +45,26 @@ Since the storage is interoperable with your Postgres database, you can also use
client libraries. Here we create a bucket called "avatars":
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
{label: 'JavaScript', value: 'JS'},
{label: 'Dart', value: 'DART'},
]}>
<TabItem value="UI">
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "Storage" section.
2. Click "Create Bucket".
3. Enter the bucket name.
4. Click "Create Bucket".
```
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Click **New Bucket** and enter a name for the bucket.
3. Click **Create Bucket**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/storage/create.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Use Postgres to create a bucket.
@@ -75,7 +74,7 @@ values ('avatars', 'avatars');
```
</TabItem>
<TabItem value="JS">
<TabItem value="javascript">
```js
// Use the JS library to create a bucket.
@@ -86,7 +85,7 @@ const { data, error } = await supabase.storage.createBucket('avatars')
[Reference.](/docs/reference/javascript/storage-createbucket)
</TabItem>
<TabItem value="DART">
<TabItem value="dart">
```dart
void main() async {
@@ -108,27 +107,26 @@ void main() async {
You can upload a file from the Dashboard, or within a browser using our JS libraries.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'JavaScript', value: 'JS'},
{label: 'Dart', value: 'DART'},
]}>
<TabItem value="UI">
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "Storage" section.
2. Select the bucket you want to upload the file into.
3. Click "Upload File".
4. Select the file you want to upload in the dialog that appears.
```
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Select the bucket you want to upload the file to.
3. Click **Upload File**.
4. Select the file you want to upload.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/storage/upload.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="JS">
<TabItem value="javascript">
```js
const avatarFile = event.target.files[0]
@@ -140,7 +138,7 @@ const { data, error } = await supabase.storage
[Reference.](/docs/reference/javascript/storage-from-upload)
</TabItem>
<TabItem value="DART">
<TabItem value="dart">
```dart
void main() async {
@@ -164,27 +162,26 @@ void main() async {
You can download a file from the Dashboard, or within a browser using our JS libraries.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'JavaScript', value: 'JS'},
{label: 'Dart', value: 'DART'},
]}>
<TabItem value="UI">
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "Storage" section.
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Select the bucket that contains the file.
3. Select the file that you want to download.
4. Click the "Download" button.
```
4. Click **Download**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/storage/download.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="JS">
<TabItem value="javascript">
```js
// Use the JS library to create a bucket.
@@ -195,7 +192,7 @@ const { data, error } = await supabase.storage.from('avatars').download('public/
[Reference.](/docs/reference/javascript/storage-from-download)
</TabItem>
<TabItem value="DART">
<TabItem value="dart">
```dart
void main() async {
@@ -216,31 +213,30 @@ void main() async {
To restrict access to your files you can use either the Dashboard or SQL.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'}
]}>
<TabItem value="UI">
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'}
]}>
<TabItem value="dashboard">
```sh
1. Go to the "Storage" section.
2. Click "Policies" in the sidebar.
3. Click "Add Policies" in the "OBJECTS" table to add policies for Files. You can also create Policies for Buckets.
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Click **Policies** in the sidebar.
3. Click **Add Policies** in the `OBJECTS` table to add policies for Files. You can also create policies for Buckets.
4. Choose whether you want the policy to apply to downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE).
5. Give your policy a unique name.
6. Write the Policy using SQL.
```
6. Write the policy using SQL.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/storage/policies.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Use the SQL to create a policy.
-- Use SQL to create a policy.
create policy "Public Access"
on storage.objects for select
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-angular
title: "Quickstart: Angular"
description: Learn how to use Supabase in your Angular App.
sidebar_label: Angular
---
import Tabs from '@theme/Tabs';
@@ -53,25 +54,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -130,27 +129,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Angular app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-expo
title: 'Quickstart: Expo'
description: Learn how to use Supabase in your React Native App.
sidebar_label: Expo
---
import Tabs from '@theme/Tabs'
@@ -37,25 +38,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -114,27 +113,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the React Native app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-flutter
title: 'Quickstart: Flutter'
description: Learn how to use Supabase in your Flutter App.
sidebar_label: Flutter
---
import Tabs from '@theme/Tabs'
@@ -43,25 +44,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -116,27 +115,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" key on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Flutter app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-ionic-angular
title: "Quickstart: Ionic Angular"
description: Learn how to use Supabase in your Ionic Angular App.
sidebar_label: Ionic Angular
---
import Tabs from '@theme/Tabs';
@@ -53,25 +54,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -130,27 +129,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Angular app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-ionic-react
title: "Quickstart: Ionic React"
description: Learn how to use Supabase in your Ionic React App.
sidebar_label: Ionic React
---
import Tabs from '@theme/Tabs';
@@ -53,25 +54,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -130,27 +129,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the React app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-ionic-vue
title: "Quickstart: Ionic Vue"
description: Learn how to use Supabase in your Ionic Vue App.
sidebar_label: Ionic Vue
---
import Tabs from '@theme/Tabs';
@@ -53,25 +54,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -130,27 +129,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Vue app from scratch.
+15 -29
View File
@@ -2,6 +2,7 @@
id: with-nextjs
title: "Quickstart: Next.js"
description: Learn how to use Supabase in your Next App.
sidebar_label: "Next.js"
---
import Tabs from '@theme/Tabs';
@@ -61,25 +62,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -140,27 +139,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Next.js app from scratch.
@@ -171,7 +157,7 @@ We can use [`create-next-app`](https://nextjs.org/docs/getting-started) to initi
an app called `supabase-nextjs`:
```bash
npx create-next-app supabase-nextjs
npx create-next-app supabase-nextjs --use-npm
cd supabase-nextjs
```
+19 -27
View File
@@ -2,9 +2,11 @@
id: with-nuxt-3
title: 'Quickstart: Nuxt 3'
description: Learn how to use Supabase in your Nuxt 3 App.
sidebar_label: Nuxt 3
---
# Quickstart: Nuxt
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Intro
@@ -42,22 +44,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultActiveId="UI"
>
<TabsPanel id="UI" label="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabsPanel>
<TabsPanel id="SQL" label="SQL">
</TabItem>
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -108,7 +111,7 @@ create policy "Anyone can upload an avatar."
```
</TabsPanel>
</TabItem>
</Tabs>
### Get the API Keys
@@ -116,25 +119,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultActiveId="UI"
>
<TabsPanel id="UI" label="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabsPanel>
</Tabs>
## Building the App
Let's start building the Vue 3 app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-react
title: 'Quickstart: React'
description: Learn how to use Supabase in your React App.
sidebar_label: React
---
import Tabs from '@theme/Tabs'
@@ -60,25 +61,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -137,27 +136,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the React app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-redwoodjs
title: 'Quickstart: RedwoodJS'
description: Learn how to use Supabase in your RedwoodJS App.
sidebar_label: RedwoodJS
---
import Tabs from '@theme/Tabs'
@@ -107,25 +108,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
4. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -190,27 +189,14 @@ Because this Quick Start does not use Prisma to manage the database schema, seed
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL as well as the `anon`, `service_role` and `JWT_SECRET` keys from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "JWT Secret" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the RedwoodJS app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-solidjs
title: 'Quickstart: SolidJS'
description: Learn how to use Supabase in your SolidJS App.
sidebar_label: SolidJS
---
import Tabs from '@theme/Tabs'
@@ -60,25 +61,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -137,27 +136,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the SolidJS app from scratch.
+16 -30
View File
@@ -2,6 +2,7 @@
id: with-svelte
title: "Quickstart: Svelte"
description: Learn how to use Supabase in your Svelte App.
sidebar_label: Svelte
---
import Tabs from '@theme/Tabs';
@@ -43,25 +44,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -122,27 +121,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Svelte app from scratch.
@@ -405,8 +391,8 @@ Now that we have all the components in place, let's update `App.svelte`:
user.set(supabase.auth.user())
supabase.auth.onAuthStateChange((_, session) => {
user.set(session.user)
supabase.auth.onAuthStateChange((state, session) => {
user.set(state === 'SIGNED_IN' && session.user)
})
</script>
+14 -29
View File
@@ -2,6 +2,7 @@
id: with-sveltekit
title: "Quickstart: SvelteKit"
description: Learn how to use Supabase in your SvelteKit App.
sidebar_label: SvelteKit
---
import Tabs from '@theme/Tabs';
@@ -43,26 +44,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "Home" section.
2. Click "SQL Editor" in the sidebar.
3. Click "User Management Starter".
4. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -123,27 +121,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Home" section.
2. Click "API" in the sidebar.
3. Click the "Authentication" heading under "API Docs".
4. Find your "SUPABASE_KEY" and "SUPABASE_URL" keys on this page (right hand side as you scroll down).
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Svelte app from scratch.
+14 -28
View File
@@ -2,6 +2,7 @@
id: with-vue-3
title: "Quickstart: Vue 3"
description: Learn how to use Supabase in your Vue 3 App.
sidebar_label: "Vue 3"
---
import Tabs from '@theme/Tabs';
@@ -43,25 +44,23 @@ Now we are going to set up the database schema. We can use the "User Management
or you can just copy/paste the SQL from below and run it yourself.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="UI">
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
```sh
1. Go to the "SQL Editor" section.
2. Click "User Management Starter".
3. Click "Run".
```
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
<TabItem value="SQL">
<TabItem value="sql">
```sql
-- Create a table for public "profiles"
@@ -122,27 +121,14 @@ create policy "Anyone can upload an avatar."
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the URL and `anon` key from the API settings.
<Tabs
defaultValue="UI"
values={[
{label: 'UI', value: 'UI'}
]}>
<TabItem value="UI">
```sh
1. Go to the "Settings" section.
2. Click "API" in the sidebar.
3. Find your API URL in this page.
4. Find your "anon" and "service_role" keys on this page.
```
1. Go to the [Settings](https://app.supabase.com/project/_/settings) page in the Dashboard.
2. Click **API** in the sidebar.
3. Find your API `URL`, `anon`, and `service_role` keys on this page.
<video width="99%" muted playsInline controls="true">
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
</Tabs>
## Building the App
Let's start building the Vue 3 app from scratch.
+9 -1
View File
@@ -1696,7 +1696,15 @@ pages:
.eq('name', 'United States')
.order('name', {foreignTable: 'cities'})
```
- name: Ordering multiple columns
js: |
```js
const { data, error } = await supabase
.from('cities')
.select('name', 'country_id')
.order('country_id', { ascending: false })
.order('name', { ascending: false })
```
range():
$ref: '@supabase/postgrest-js."lib/PostgrestFilterBuilder".PostgrestFilterBuilder.range'
examples: