Merge branch 'master' into feat/case-studies

This commit is contained in:
Jonathan Summers-Muir committed 2021-11-04 15:43:35 +08:00
commit 32d4cd5ba2
168 files changed
+3616 -1380

No files matched your search

+2 -2
View File
@@ -16,8 +16,8 @@ import Process from '@site/docs/careers/snippets/process.mdx'
- Be the business intelligence star player at Supabase by helping dig deep into the data we are generating. Deep knowledge of SQL and relevant tooling is a must.
- Help customer success & sales team by working to identify and monitor:
- Usage Insights
- Find and segment cohorts based around account level data, behaviour, traffic sources, and measure their subsequent behaviours
- Find and monitor product qualified leads based around account and behaviour characteristics
- Find and segment cohorts based around account level data, behavior, traffic sources, and measure their subsequent behaviours
- Find and monitor product qualified leads based around account and behavior characteristics
- Customer health segmentation into actionable cohorts (e.g. healthy, churn, at risk)
- Help identify opportunities high touch, low touch, & tech touch customer success & sales approaches
- Help sales & customer success identify opportunity for unscheduled outreach
-7
View File
@@ -1,7 +0,0 @@
{
"rewrites": [
{ "source": "/", "destination": "https://www-internal.supabase.io/new" },
{ "source": "/beta", "destination": "https://www-internal.supabase.io/new/beta" }
],
"trailingSlash": false
}
@@ -29,7 +29,7 @@ export default function Header() {
<div className="flex-shrink-0 flex items-center text-white">
<img
className="h-8 w-auto"
src="https://supabase.io/new/images/logo-dark.png"
src="https://supabase.io/images/logo-dark.png"
alt="supabase"
/>
</div>
-87
View File
@@ -1,87 +0,0 @@
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Strict-Transport-Security",
"value": ""
}
]
}
],
"rewrites": [
{ "source": "/new/:match*", "destination": "http://localhost:3000/new/:match*" },
{ "source": "/", "destination": "http://localhost:3000/new" },
{ "source": "/beta", "destination": "http://localhost:3000/new/beta" },
{ "source": "/blog", "destination": "http://localhost:3000/new/blog" },
{ "source": "/database", "destination": "http://localhost:3000/new/database" },
{ "source": "/auth", "destination": "http://localhost:3000/new/auth" },
{
"source": "/blog/:match*",
"destination": "http://localhost:3000/new/blog/:match*"
},
{ "source": "/rss", "destination": "http://localhost:3000/new/rss.xml" },
{ "source": "/:name.:extension", "destination": "http://localhost:3005/:name.:extension" },
{
"source": "/:asset/:name.:extension",
"destination": "http://localhost:3005/:asset/:name.:extension"
},
{ "source": "/:match*", "destination": "http://localhost:3005/:match*/" }
],
"redirects": [
{
"source": "/blog/2020/07/10/surviving-hacker-news",
"destination": "/blog/2020/07/10/alpha-launch-postmortem"
},
{
"source": "/docs/common/_CommonResponses",
"destination": "/docs"
},
{ "source": "/docs/common/_DummyData", "destination": "/docs" },
{ "source": "/docs/common/_FromFunction", "destination": "/docs" },
{ "source": "/docs/common/filters/_adj", "destination": "/docs/client/ajv" },
{ "source": "/docs/common/filters/_cd", "destination": "/docs/client/cd" },
{ "source": "/docs/common/filters/_cs", "destination": "/docs/client/cs" },
{ "source": "/docs/common/filters/_eq", "destination": "/docs/client/eq" },
{ "source": "/docs/common/filters/_filter", "destination": "/docs/client/filter" },
{ "source": "/docs/common/filters/_gt", "destination": "/docs/client/gt" },
{ "source": "/docs/common/filters/_gte", "destination": "/docs/client/gte" },
{ "source": "/docs/common/filters/_ilike", "destination": "/docs/client/ilike" },
{ "source": "/docs/common/filters/_in", "destination": "/docs/client/in" },
{ "source": "/docs/common/filters/_is", "destination": "/docs/client/is" },
{ "source": "/docs/common/filters/_like", "destination": "/docs/client/like" },
{ "source": "/docs/common/filters/_lt", "destination": "/docs/client/lt" },
{ "source": "/docs/common/filters/_lte", "destination": "/docs/client/lte" },
{ "source": "/docs/common/filters/_match", "destination": "/docs/client/match" },
{ "source": "/docs/common/filters/_neq", "destination": "/docs/client/neq" },
{ "source": "/docs/common/filters/_not", "destination": "/docs/client/not" },
{ "source": "/docs/common/filters/_nxl", "destination": "/docs/client/nxl" },
{ "source": "/docs/common/filters/_nxr", "destination": "/docs/client/nxr" },
{ "source": "/docs/common/filters/_or", "destination": "/docs/client/or" },
{ "source": "/docs/common/filters/_ova", "destination": "/docs/client/ov" },
{ "source": "/docs/common/filters/_ovr", "destination": "/docs/client/ov" },
{ "source": "/docs/common/filters/_sl", "destination": "/docs/client/sl" },
{ "source": "/docs/common/filters/_sr", "destination": "/docs/client/sr" },
{ "source": "/docs/library/authentication", "destination": "/docs/guides/auth" },
{ "source": "/docs/library/delete", "destination": "/docs/client/delete" },
{ "source": "/docs/library/get", "destination": "/docs/client/select" },
{ "source": "/docs/library/getting-started", "destination": "/docs/client/supabase-client" },
{ "source": "/docs/library/patch", "destination": "/docs/client/update" },
{ "source": "/docs/library/post", "destination": "/docs/client/insert" },
{ "source": "/docs/library/stored-procedures", "destination": "/docs/client/rpc" },
{ "source": "/docs/library/subscribe", "destination": "/docs/client/subscribe" },
{ "source": "/docs/library/user-management", "destination": "/docs/guides/auth" },
{ "source": "/docs/postgres/postgres-intro", "destination": "/docs/postgres/server/about" },
{ "source": "/docs/realtime/about", "destination": "/docs/realtime/server/about" },
{ "source": "/docs/realtime/aws", "destination": "/docs/postgres/server/aws" },
{
"source": "/docs/realtime/digitalocean",
"destination": "/docs/postgres/server/digitalocean"
},
{ "source": "/docs/realtime/docker", "destination": "/docs/postgres/server/docker" },
{ "source": "/docs/realtime/source", "destination": "/docs/postgres/server/about" }
],
"trailingSlash": false
}
-240
View File
@@ -1,240 +0,0 @@
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Strict-Transport-Security",
"value": ""
},
{
"key": "X-Robots-Tag",
"value": "all"
},
{
"key": "X-Frame-Options",
"value": "DENY"
}
]
}
],
"rewrites": [
{
"source": "/new/_next/image:match*",
"destination": "https://www-internal.supabase.io/_next/image:match*"
},
{ "source": "/new/:match*", "destination": "https://www-internal.supabase.io/new/:match*" },
{ "source": "/", "destination": "https://www-internal.supabase.io/new" },
{ "source": "/blog", "destination": "https://www-internal.supabase.io/new/blog" },
{
"source": "/blog/:match*",
"destination": "https://www-internal.supabase.io/new/blog/:match*"
},
{ "source": "/rss", "destination": "https://www-internal.supabase.io/new/rss.xml" },
{ "source": "/rss.xml", "destination": "https://www-internal.supabase.io/new/rss.xml" },
{ "source": "/blog/rss.xml", "destination": "https://www-internal.supabase.io/new/rss.xml" },
{ "source": "/blog/rss", "destination": "https://www-internal.supabase.io/new/rss.xml" },
{ "source": "/beta", "destination": "https://www-internal.supabase.io/new/beta" },
{ "source": "/pricing", "destination": "https://www-internal.supabase.io/new/pricing" },
{ "source": "/database", "destination": "https://www-internal.supabase.io/new/database" },
{ "source": "/auth", "destination": "https://www-internal.supabase.io/new/auth" },
{ "source": "/storage", "destination": "https://www-internal.supabase.io/new/storage" },
{ "source": "/support", "destination": "https://www-internal.supabase.io/new/support" },
{
"source": "/brand-assets",
"destination": "https://www-internal.supabase.io/new/brand-assets"
},
{ "source": "/:match*", "destination": "https://docs-rose.vercel.app/:match*" }
],
"redirects": [
{
"source": "/blog/2021/03/08/toad-a-link-shorterner-with-simple-apis-for-low-coders",
"destination": "/blog/2021/03/08/toad-a-link-shortener-with-simple-apis-for-low-coders"
},
{
"source": "/blog/2020/07/10/surviving-hacker-news",
"destination": "/blog/2020/07/10/alpha-launch-postmortem"
},
{
"source": "/docs/common/_CommonResponses",
"destination": "/docs"
},
{ "source": "/docs/common/_DummyData", "destination": "/docs" },
{ "source": "/docs/common/_FromFunction", "destination": "/docs" },
{
"source": "/docs/common/filters/_adj",
"destination": "/docs/reference/javascript/rangeAdjacent"
},
{
"source": "/docs/common/filters/_cd",
"destination": "/docs/reference/javascript/containedBy"
},
{ "source": "/docs/common/filters/_cs", "destination": "/docs/reference/javascript/contains" },
{ "source": "/docs/common/filters/_eq", "destination": "/docs/reference/javascript/eq" },
{
"source": "/docs/common/filters/_filter",
"destination": "/docs/reference/javascript/filter"
},
{ "source": "/docs/common/filters/_gt", "destination": "/docs/reference/javascript/gt" },
{ "source": "/docs/common/filters/_gte", "destination": "/docs/reference/javascript/gte" },
{ "source": "/docs/common/filters/_ilike", "destination": "/docs/reference/javascript/ilike" },
{ "source": "/docs/common/filters/_in", "destination": "/docs/reference/javascript/in" },
{ "source": "/docs/common/filters/_is", "destination": "/docs/reference/javascript/is" },
{ "source": "/docs/common/filters/_like", "destination": "/docs/reference/javascript/like" },
{ "source": "/docs/common/filters/_lt", "destination": "/docs/reference/javascript/lt" },
{ "source": "/docs/common/filters/_lte", "destination": "/docs/reference/javascript/lte" },
{ "source": "/docs/common/filters/_match", "destination": "/docs/reference/javascript/match" },
{ "source": "/docs/common/filters/_neq", "destination": "/docs/reference/javascript/neq" },
{ "source": "/docs/common/filters/_not", "destination": "/docs/reference/javascript/not" },
{ "source": "/docs/common/filters/_nxl", "destination": "/docs/reference/javascript/rangeGte" },
{ "source": "/docs/common/filters/_nxr", "destination": "/docs/reference/javascript/rangeLte" },
{ "source": "/docs/common/filters/_or", "destination": "/docs/reference/javascript/or" },
{ "source": "/docs/common/filters/_ova", "destination": "/docs/reference/javascript/overlaps" },
{ "source": "/docs/common/filters/_ovr", "destination": "/docs/reference/javascript/overlaps" },
{ "source": "/docs/common/filters/_sl", "destination": "/docs/reference/javascript/rangeLt" },
{ "source": "/docs/common/filters/_sr", "destination": "/docs/reference/javascript/rangeGt" },
{ "source": "/docs/library/authentication", "destination": "/docs/guides/auth" },
{ "source": "/docs/library/delete", "destination": "/docs/reference/javascript/delete" },
{ "source": "/docs/library/get", "destination": "/docs/reference/javascript/select" },
{
"source": "/docs/library/getting-started",
"destination": "/docs/reference/javascript/supabase-client"
},
{ "source": "/docs/library/patch", "destination": "/docs/reference/javascript/update" },
{ "source": "/docs/library/post", "destination": "/docs/reference/javascript/insert" },
{
"source": "/docs/library/stored-procedures",
"destination": "/docs/reference/javascript/rpc"
},
{ "source": "/docs/library/subscribe", "destination": "/docs/reference/javascript/subscribe" },
{ "source": "/docs/library/user-management", "destination": "/docs/guides/auth" },
{ "source": "/docs/postgres/postgres-intro", "destination": "/docs/postgres/server/about" },
{ "source": "/docs/realtime/about", "destination": "/docs/realtime/server/about" },
{ "source": "/docs/realtime/aws", "destination": "/docs/postgres/server/aws" },
{
"source": "/docs/realtime/digitalocean",
"destination": "/docs/postgres/server/digitalocean"
},
{ "source": "/docs/realtime/docker", "destination": "/docs/postgres/server/docker" },
{ "source": "/docs/realtime/source", "destination": "/docs/postgres/server/about" },
{
"source": "/docs/client/supabase-client",
"destination": "/docs/reference/javascript/supabase-client"
},
{ "source": "/docs/client/installing", "destination": "/docs/reference/javascript/installing" },
{
"source": "/docs/client/initializing",
"destination": "/docs/reference/javascript/initializing"
},
{
"source": "/docs/client/generating-types",
"destination": "/docs/reference/javascript/generating-types"
},
{
"source": "/docs/client/auth-signup",
"destination": "/docs/reference/javascript/auth-signup"
},
{
"source": "/docs/client/auth-signin",
"destination": "/docs/reference/javascript/auth-signin"
},
{
"source": "/docs/client/auth-signout",
"destination": "/docs/reference/javascript/auth-signout"
},
{
"source": "/docs/client/auth-session",
"destination": "/docs/reference/javascript/auth-session"
},
{ "source": "/docs/client/auth-user", "destination": "/docs/reference/javascript/auth-user" },
{
"source": "/docs/client/auth-update",
"destination": "/docs/reference/javascript/auth-update"
},
{
"source": "/docs/client/auth-onauthstatechange",
"destination": "/docs/reference/javascript/auth-onauthstatechange"
},
{
"source": "/docs/client/reset-password-email",
"destination": "/docs/reference/javascript/reset-password-email"
},
{ "source": "/docs/client/select", "destination": "/docs/reference/javascript/select" },
{ "source": "/docs/client/insert", "destination": "/docs/reference/javascript/insert" },
{ "source": "/docs/client/update", "destination": "/docs/reference/javascript/update" },
{ "source": "/docs/client/delete", "destination": "/docs/reference/javascript/delete" },
{ "source": "/docs/client/rpc", "destination": "/docs/reference/javascript/rpc" },
{ "source": "/docs/client/subscribe", "destination": "/docs/reference/javascript/subscribe" },
{
"source": "/docs/client/removesubscription",
"destination": "/docs/reference/javascript/removesubscription"
},
{
"source": "/docs/client/getsubscriptions",
"destination": "/docs/reference/javascript/getsubscriptions"
},
{
"source": "/docs/client/using-modifiers",
"destination": "/docs/reference/javascript/using-modifiers"
},
{ "source": "/docs/client/limit", "destination": "/docs/reference/javascript/limit" },
{ "source": "/docs/client/order", "destination": "/docs/reference/javascript/order" },
{ "source": "/docs/client/range", "destination": "/docs/reference/javascript/range" },
{ "source": "/docs/client/single", "destination": "/docs/reference/javascript/single" },
{
"source": "/docs/client/using-filters",
"destination": "/docs/reference/javascript/using-filters"
},
{ "source": "/docs/client/filter", "destination": "/docs/reference/javascript/filter" },
{ "source": "/docs/client/or", "destination": "/docs/reference/javascript/or" },
{ "source": "/docs/client/not", "destination": "/docs/reference/javascript/not" },
{ "source": "/docs/client/match", "destination": "/docs/reference/javascript/match" },
{ "source": "/docs/client/eq", "destination": "/docs/reference/javascript/eq" },
{ "source": "/docs/client/neq", "destination": "/docs/reference/javascript/neq" },
{ "source": "/docs/client/gt", "destination": "/docs/reference/javascript/gt" },
{ "source": "/docs/client/gte", "destination": "/docs/reference/javascript/gte" },
{ "source": "/docs/client/lt", "destination": "/docs/reference/javascript/lt" },
{ "source": "/docs/client/lte", "destination": "/docs/reference/javascript/lte" },
{ "source": "/docs/client/like", "destination": "/docs/reference/javascript/like" },
{ "source": "/docs/client/ilike", "destination": "/docs/reference/javascript/ilike" },
{ "source": "/docs/client/is", "destination": "/docs/reference/javascript/is" },
{ "source": "/docs/client/in", "destination": "/docs/reference/javascript/in" },
{ "source": "/docs/client/gte", "destination": "/docs/reference/javascript/gte" },
{ "source": "/docs/client/cs", "destination": "/docs/reference/javascript/contains" },
{ "source": "/docs/client/cd", "destination": "/docs/reference/javascript/containedBy" },
{ "source": "/docs/client/sl", "destination": "/docs/reference/javascript/rangeLt" },
{ "source": "/docs/client/sr", "destination": "/docs/reference/javascript/rangeGt" },
{ "source": "/docs/client/nxl", "destination": "/docs/reference/javascript/rangeGte" },
{ "source": "/docs/client/nxr", "destination": "/docs/reference/javascript/rangeLte" },
{ "source": "/docs/client/adj", "destination": "/docs/reference/javascript/rangeAdjacent" },
{ "source": "/docs/client/ov", "destination": "/docs/reference/javascript/overlaps" },
{ "source": "/docs/client/ova", "destination": "/docs/reference/javascript/overlaps" },
{ "source": "/docs/client/fts", "destination": "/docs/reference/javascript/textSearch" },
{ "source": "/docs/client/plfts", "destination": "/docs/reference/javascript/textSearch" },
{ "source": "/docs/client/phfts", "destination": "/docs/reference/javascript/textSearch" },
{ "source": "/docs/client/wfts", "destination": "/docs/reference/javascript/textSearch" },
{ "source": "/blog/page/:number", "destination": "/blog" },
{ "source": "/blog/tags", "destination": "/blog" },
{ "source": "/docs/pricing", "destination": "/pricing" },
{ "source": "/docs/careers", "destination": "https://about.supabase.com/careers" },
{ "source": "/docs/careers/:match*", "destination": "https://about.supabase.com/careers//:match*" },
{ "source": "/docs/resources", "destination": "/docs/guides" },
{ "source": "/docs/reference/postgres/getting-started", "destination": "/docs/guides/database/introduction" },
{ "source": "/reference/postgres/connection-strings", "destination": "/docs/guides/database/connecting/connecting-to-postgres" },
{ "source": "/docs/reference/postgres/schemas", "destination": "/docs/guides/database/tables" },
{ "source": "/docs/reference/postgres/tables", "destination": "/docs/guides/database/tables" },
{ "source": "/docs/guides/database/resource-management", "destination": "/docs/guides/database/timeouts" },
{ "source": "/docs/reference/postgres/database-passwords", "destination": "/docs/guides/database/managing-passwords" },
{ "source": "/docs/reference/postgres/changing-timezones", "destination": "/docs/guides/database/managing-timezones" },
{ "source": "/docs/reference/postgres/publications", "destination": "/docs/guides/database/replication" },
{ "source": "/docs/guides/platform", "destination": "/docs/guides/hosting/platform" },
{ "source": "/docs/guides/self-hosting", "destination": "/docs/guides/hosting/overview" }
],
"trailingSlash": false
}
+7 -1
View File
@@ -6,6 +6,7 @@ slug: /
hide_table_of_contents: true
---
import useBaseUrl from '@docusaurus/useBaseUrl'
import Link from '@docusaurus/Link'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
@@ -90,7 +91,12 @@ Supabase is just Postgres, which makes it compatible with a large number of tool
<Link class="card" to={x.href}>
<div class="card__body" style={{ display: 'flex', gap: 20, alignItems: 'center' }}>
{x.logo && (
<img src={x.logo} alt={x.name} width="20" style={{ display: 'block', maxHeight: 20 }} />
<img
src={useBaseUrl(x.logo)}
alt={x.name}
width="20"
style={{ display: 'block', maxHeight: 20 }}
/>
)}
<p>{x.name}</p>
</div>
+6 -6
View File
@@ -164,15 +164,15 @@ The criteria used to determine the period for which personal information about y
4. **Legal Obligation.** Where we are processing personal information based on a legal obligation, we generally will retain the information for the period of time necessary to fulfill the legal obligation.
5. **Legal Claim.** We may need to apply a "legal hold" that retains information beyond our typical retention period where we face threat of legal claim.  In that case, we will retain the information until the hold is removed, which typically means the claim or threat of claim has been resolved.
In all cases, in addition to the purposes and legal bases, we consider the amount, nature and sensitivity of the personal information, as well as the potential risk of harm from unauthorised use or disclosure of your personal information.
In all cases, in addition to the purposes and legal bases, we consider the amount, nature and sensitivity of the personal information, as well as the potential risk of harm from unauthorized use or disclosure of your personal information.
### 4. Recipients of Personal Information
In addition to the recipients listed in Annexes 1 and 2, we may also share your personal information with the following (as required in accordance with the uses set out in Annexes 1 and 2):
1. **Service providers and advisors**: we may share your personal information with third party vendors and other service providers that perform services for us or on our behalf, which may include providing professional services, such as legal and accounting services, mailing, email or chat services, fraud prevention, web hosting, or providing analytic services.
2. **Affiliates**. Other companies owned by or under common ownership as Supabase, including our subsidiaries (i.e., any organisation we own or control) and our ultimate holding company (i.e., any organisation that owns or controls us) and any subsidiaries it owns. These companies will use your personal information in the same way as we can under these Privacy Disclosures.
3. **Purchasers and third parties in connection with a business transaction**: your personal information may be disclosed to third parties in connection with a transaction, such as a merger, sale of assets or shares, reorganisation, financing, change of control or acquisition of all or a portion of our business.
2. **Affiliates**. Other companies owned by or under common ownership as Supabase, including our subsidiaries (i.e., any organization we own or control) and our ultimate holding company (i.e., any organization that owns or controls us) and any subsidiaries it owns. These companies will use your personal information in the same way as we can under these Privacy Disclosures.
3. **Purchasers and third parties in connection with a business transaction**: your personal information may be disclosed to third parties in connection with a transaction, such as a merger, sale of assets or shares, reorganization, financing, change of control or acquisition of all or a portion of our business.
4. **Law enforcement, regulators and other parties for legal reasons**: we may share your personal information with third parties as required by law or if we reasonably believe that such action is necessary to (i) comply with the law and the reasonable requests of law enforcement; (ii) detect and investigate illegal activities and breaches of agreements, including our Terms; and/or (iii) exercise or protect the rights, property, or personal safety of Supabase, its users or others.
### 5. Marketing and Advertising
@@ -183,11 +183,11 @@ We will only send you marketing messages if you have given us your consent to do
### 6. Storing and transferring your personal information
**Security**. We implement appropriate technical and organisational measures to protect your personal information against accidental or unlawful destruction, loss, change or damage. All personal information we collect will be stored by our cloud hosting provider on secure servers. We will never send you unsolicited emails or contact you by phone requesting credit or debit card information or national identification numbers.
**Security**. We implement appropriate technical and organizational measures to protect your personal information against accidental or unlawful destruction, loss, change or damage. All personal information we collect will be stored by our cloud hosting provider on secure servers. We will never send you unsolicited emails or contact you by phone requesting credit or debit card information or national identification numbers.
**International Transfers of your Personal Information**. The personal information we collect may be transferred to and stored in countries outside of the jurisdiction you are in where we and our third party service providers have operations. If you are located in the EEA, United Kingdom or Switzerland, your personal information may be processed outside of those regions, including in the United States.
In the event of such a transfer, we ensure that: (i) the personal information is transferred to countries recognised as offering an equivalent level of protection; or (ii) the transfer is made pursuant to appropriate safeguards, such as standard data protection clauses adopted by the European Commission.
In the event of such a transfer, we ensure that: (i) the personal information is transferred to countries recognized as offering an equivalent level of protection; or (ii) the transfer is made pursuant to appropriate safeguards, such as standard data protection clauses adopted by the European Commission.
If you wish to enquire further about these safeguards used, please contact us using the details set out at the end of these Privacy Disclosures.
@@ -222,7 +222,7 @@ Due to the confidential nature of data processing we may ask you to provide proo
Our European Services uses cookies and similar technologies such as pixels and Local Storage Objects (LSOs) like HTML5 (together "**_cookies_**") to distinguish you from other users of our European Services. This helps us to provide you with a good experience when you browse our European Services and also allows us to monitor and analyse how you use and interact with our European Services so that we can continue to improve our European Services.
Cookies are pieces of code that allow for personalisation of our European Services experience by saving your information such as user ID and other preferences. A cookie is a small data file that we transfer to your computer's hard disk for record-keeping purposes.
Cookies are pieces of code that allow for personalization of our European Services experience by saving your information such as user ID and other preferences. A cookie is a small data file that we transfer to your computer's hard disk for record-keeping purposes.
We use the following types of cookies:
+1 -1
View File
@@ -1,7 +1,7 @@
---
id: going-into-prod
title: Going into Prod Checklist
description: 'Things to do before making your app publicaly available'
description: 'Things to do before making your app publicly available'
---
After developing your project, and deciding it's time to Go Live With Real Users, you should run through this checklist to ensure that your project is:
+1 -2
View File
@@ -15,8 +15,7 @@ These guides help you unleash the power of PostgreSQL, the world's most advanced
Authenticating users isn't the most exciting job for most developers, so Supabase makes it quick and simple, while maintaining security and performance.
<!--
<!--
<a className="card" href="/docs/guides/database" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Database</h3>
+12 -4
View File
@@ -7,7 +7,6 @@ description: Auto-generating and Realtime APIs.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Overview
Supabase generates APIs directly from your Database schema. The API is:
@@ -30,6 +29,15 @@ It provides everything you need from a CRUD API:
- Works with Postgres Functions
- Works with the Postgres security model - including Row Level Security, Roles, and Grants.
<iframe
className="w-full video-with-border"
width="640"
height="385"
src="https://www.youtube-nocookie.com/embed/rPAJJFdtPw0"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
### Realtime API
@@ -68,7 +76,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -108,7 +116,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -222,7 +230,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+13 -3
View File
@@ -9,12 +9,22 @@ import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import providers from '@site/src/data/authProviders'
<iframe
className="w-full video-with-border"
width="640"
height="385"
src="https://www.youtube-nocookie.com/embed/6ow_jW4epf8"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
## User Management
Supabase makes it simple to manage your users.
<video width="99%" muted playsInline controls="true">
<source src="/videos/auth-zoom2.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/auth-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
When users sign up, Supabase assigns them a unique ID. You can reference this ID anywhere in your database. For example, you might create a `profiles` table referencing `id` in the `auth.users` table using a `user_id` field.
@@ -50,7 +60,7 @@ You can enable providers by navigating to Authentication > Settings > External O
Authentication only gets you so far. When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security (RLS)](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). Supabase makes it simple to turn RLS on and off.
<video width="99%" muted playsInline controls="true">
<source src="/videos/rls-zoom2.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/rls-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
## Policies
@@ -58,7 +68,7 @@ Authentication only gets you so far. When you need granular authorization rules,
[Policies](https://www.postgresql.org/docs/current/sql-createpolicy.html) are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs.
<video width="99%" muted playsInline controls="true">
<source src="/videos/policies-zoom2.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/policies-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
With policies, your database becomes the rules engine. Instead of repetitively filtering your queries, like this ...
+1 -1
View File
@@ -71,7 +71,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Configure your Services ID
+1 -1
View File
@@ -40,7 +40,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create a Bitbucket OAuth app
+1 -1
View File
@@ -45,7 +45,7 @@ In the next step you require a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create a Discord Application
+1 -1
View File
@@ -48,7 +48,7 @@ The next step requires a callback URI, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Set up FaceBook Login for your Facebook App
+1 -1
View File
@@ -48,7 +48,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Register a new OAuth application
+1 -1
View File
@@ -39,7 +39,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create your GitLab Application
+3 -3
View File
@@ -62,7 +62,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create your credentials
@@ -71,8 +71,8 @@ The next step requires a callback URL, which looks like this:
- Click `Create Credentials` near the top then select `OAuth client ID`
- On the `Create OAuth client ID` page, select your application type. If you're not sure, choose `Web application`.
- Fill in your app name.
- At the bottom, under `Authorised redirect URIs` click `Add URI`.
- Enter your callback URI under `Authorised redirect URIs` at the bottom.
- At the bottom, under `Authorized redirect URIs` click `Add URI`.
- Enter your callback URI under `Authorized redirect URIs` at the bottom.
- Enter your callback URI in the `Valid OAuth Redirect URIs` box.
- Click `Save Changes` at the bottom right.
- Click `Create`.
+1 -1
View File
@@ -44,7 +44,7 @@ In the next step you require a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create a Twitch Application
+1 -1
View File
@@ -39,7 +39,7 @@ The next step requires a callback URL, which looks like this:
- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`.
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
### Create a Twitter OAuth app
+14 -2
View File
@@ -11,10 +11,22 @@ import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import providers from '@site/src/data/authProviders'
<iframe
className="w-full video-with-border"
width="640"
height="385"
src="https://www.youtube-nocookie.com/embed/6ow_jW4epf8"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
## Introduction
Supabase Auth is designed to work with Postgres. There are two parts to every Auth system:
- Authentication: should this person be allowed in? If yes, who are they?
- Authorization: once they are in, what are they allowed to do?
- **Authentication:** should this person be allowed in? If yes, who are they?
- **Authorization:** once they are in, what are they allowed to do?
## Authentication
+1 -1
View File
@@ -46,7 +46,7 @@ Returns the role of the user making the request. In most cases this is either `a
### `auth.email()`
Retuns the email of the user making the request.
Returns the email of the user making the request.
## Examples
+1 -1
View File
@@ -370,7 +370,7 @@ const { data, error } = await supabase
```py
data = supabase.table('cities').insert({'name': 'Gotham', 'country_id': 556 }).execute()
# assert if insert resonse is a success
# assert if insert response is a success
assert data.get("status_code") in (200, 201)
# bulk insert
+4 -4
View File
@@ -23,7 +23,7 @@ Dig into the relationships within your data.
<video width="99%" loop="" muted="" playsInline="" controls="true">
<source src="/videos/relational-drilldown-zoom.mp4" type="video/mp4" />
<source src="/docs/videos/relational-drilldown-zoom.mp4" type="video/mp4" />
</video>
@@ -32,7 +32,7 @@ Dig into the relationships within your data.
You can duplicate your tables, just like you would inside a spreadsheet.
<video width="99%" muted playsInline controls={true}>
<source src="/videos/duplicate-tables.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/duplicate-tables.mp4" type="video/mp4" muted playsInline />
</video>
@@ -41,7 +41,7 @@ You can duplicate your tables, just like you would inside a spreadsheet.
Supabase comes with a SQL Editor. You can also save your favorite queries to run later!
<video width="99%" muted playsInline controls={true}>
<source src="/videos/favorites.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/favorites.mp4" type="video/mp4" muted playsInline />
</video>
@@ -60,7 +60,7 @@ To expand the functionality of your Postgres database, you can use extensions.
You can enable Postgres extensions with the click of a button within the Supabase dashboard.
<video width="99%" muted playsInline controls={true}>
<source src="/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
[Learn more](/docs/guides/database/extensions) about all the extensions provided on Supabase.
@@ -55,7 +55,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/pgbouncer-connection.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/pgbouncer-connection.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -25,7 +25,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/postgres-connection.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/postgres-connection.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+1 -1
View File
@@ -33,7 +33,7 @@ values={[
<video width="99%" muted playsInline controls={true}>
<source src="/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
@@ -40,7 +40,7 @@ values={[
```
<video width="99%" muted playsInline controls={true}>
<source src="/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -20,8 +20,8 @@ For this guide we'll use the following example data:
<Tabs
defaultValue="Data"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'Data', value: 'Data'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="SQL">
@@ -39,7 +39,7 @@ values
('The Poky Little Puppy','Janette Sebring Lowrey','Puppy is slower than other, bigger animals.'),
('The Tale of Peter Rabbit','Beatrix Potter','Rabbit eats some vegetables.'),
('Tootle','Gertrude Crampton','Little toy train has big dreams.'),
('Green Eggs and Ham','Dr. Seuss','Sam has changing food preferences and eats unusally colored food.'),
('Green Eggs and Ham','Dr. Seuss','Sam has changing food preferences and eats unusually colored food.'),
('Harry Potter and the Goblet of Fire','J.K. Rowling','Fourth year of school starts, big drama ensues.');
```
@@ -51,7 +51,7 @@ values
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | Rabbit eats some vegetables. |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
| 4 | Green Eggs and Ham | Dr. Seuss | Sam has changing food preferences and eats unusally colored food. |
| 4 | Green Eggs and Ham | Dr. Seuss | Sam has changing food preferences and eats unusually colored food. |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. |
</TabItem>
+303
View File
@@ -0,0 +1,303 @@
---
id: functions
title: Functions
description: Creating and using Postgres functions.
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html).
These functions live inside your database, and they can be [used with the API](/docs/reference/javascript/rpc).
## Quick demo
<iframe
className="w-full video-with-border"
width="640"
height="385"
src="https://www.youtube-nocookie.com/embed/MJZCCpCYEqk"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
## Creating Functions
Supabase provides several options for creating database functions. You can use the Dashboard or create them directly using SQL.
We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/database/connecting/connecting-to-postgres) to your database
and run the SQL queries yourself.
1. Go to the "SQL editor" section.
2. Click "New Query".
3. Enter the SQL to create or replace your Database function.
4. Click "Run" or cmd+enter (ctrl+enter).
## Examples
### Data set
For this guide we'll use the following example data:
<Tabs
defaultValue="Data"
values={[
{label: 'Data', value: 'Data'},
{label: 'SQL', value: 'SQL'},
]}>
<TabItem value="SQL">
```sql
create table planets (
id serial primary key,
name text
);
insert into planets (id, name)
values
(1, 'Tattoine'),
(2, 'Alderaan'),
(3, 'Kashyyyk');
create table people (
id serial primary key,
name text,
planet_id bigint references planets
);
insert into people (id, name, planet_id)
values
(1, 'Anakin Skywalker', 1),
(2, 'Luke Skywalker', 1),
(3, 'Princess Leia', 2),
(4, 'Chewbacca', 3);
```
</TabItem>
<TabItem value="Data">
<h4>Planets</h4>
| id | name |
| ---- | ---- |
| 1 | Tattoine |
| 2 | Alderaan |
| 3 | Kashyyyk |
<h4>People</h4>
| id | name | planet_id |
| ---- | ---- | ---- |
| 1 | Anakin Skywalker | 1 |
| 2 | Luke Skywalker | 1 |
| 3 | Princess Leia | 2 |
| 4 | Chewbacca | 3 |
</TabItem>
</Tabs>
### Basic function
A basic example which returns a string "hello world".
```sql
create or replace function hello_world() -- 1
returns text -- 2
language sql -- 3
as $$ -- 4
select 'hello world'; -- 5
$$; --6
```
<details>
<summary>Show/Hide Details</summary>
At it's most basic a function has the following parts:
1. `create or replace function hello_world()`: The function declaration, where `hello_world` is the name of the function. You can use either `create` when creating a new function or `replace` when replacing an existing function. Or you can use `create or replace` together to handle either.
2. `returns text`: The type of data that the function returns. If it returns nothing, you can `return void`.
3. `language sql`: The language used inside the function body. This can also be a procedural language: `plpgsql`, `plv8`, `plpython`, etc.
4. `as $$`: The function wrapper. Anything enclosed inside the `$$` symbols will be part of the function body.
5. `select 'hello world';`: A simple function body. The final `select` statement inside a function body will be returned if there are no statements following it.
6. `$$;`: The closing symbols of the funciton wrapper.
</details>
#### Execute
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JS'},
{label: 'Dart', value: 'Dart'},
]}>
<TabItem value="SQL">
```sql
select hello_world();
```
</TabItem>
<TabItem value="JS">
```js
const { data, error } = supabase
.rpc('hello_world')
```
Reference: [rpc()](/docs/reference/javascript/rpc)
</TabItem>
<TabItem value="Dart">
```dart
final res = await supabase
.rpc('hello_world')
.execute();
```
Reference: [rpc()](/docs/reference/dart/rpc)
</TabItem>
</Tabs>
### Return table sets
A basic example which return all the `planets` in our example data set.
```sql
create or replace function get_planets()
returns setof planets
language sql
as $$
select * from planets;
$$;
```
#### Execute
Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the first planet:
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JS'},
{label: 'Dart', value: 'Dart'},
]}>
<TabItem value="SQL">
```sql
select *
from get_planets()
where id = 1;
```
</TabItem>
<TabItem value="JS">
```js
const { data, error } = supabase
.rpc('get_planets')
.eq('id', 1)
```
Reference: [rpc()](/docs/reference/javascript/rpc)
</TabItem>
<TabItem value="Dart">
```dart
final res = await supabase
.rpc('get_planets')
.eq('id', 1)
.execute();
```
Reference: [rpc()](/docs/reference/dart/rpc)
</TabItem>
</Tabs>
### With parameters
A basic example which will insert a new planet into the `planets` and return the new ID. Note that this time we're using the `plpgsql` language.
```sql
create or replace function add_planet(name text)
returns bigint
language plpgsql
as $$
declare
new_row bigint;
begin
insert into planets(name)
values (add_planet.name)
returning id into new_row;
return new_row;
end;
$$;
```
#### Execute
Because this function returns a table set, we can also apply filters and selectors. For exaple, if we only wanted the `name` of the first planet:
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JS'},
{label: 'Dart', value: 'Dart'},
]}>
<TabItem value="SQL">
```sql
select * from add_planet('Jakku');
```
</TabItem>
<TabItem value="JS">
```js
const { data, error } = supabase
.rpc('add_planet', { name: 'Jakku' })
```
Reference: [rpc()](/docs/reference/javascript/rpc)
</TabItem>
<TabItem value="Dart">
```dart
final res = await supabase
.rpc('add_planet', params: { 'name': 'Jakku' })
.execute();
```
Reference: [rpc()](/docs/reference/dart/rpc)
</TabItem>
</Tabs>
## Resources
- PostgreSQL Official Docs: [Chapter 9. Functions and Operators](https://www.postgresql.org/docs/current/functions.html)
- PostgreSQL Reference: [CREATE FUNCTION](https://www.postgresql.org/docs/9.1/sql-createfunction.html)
+1 -1
View File
@@ -20,7 +20,7 @@ This package included a query language called "PostQUEL".
In 1994, Postgres95 was built on top of POSTGRES code, adding an SQL language interpreter as a replacement for PostQUEL.
Eventually, Postgres95 was renamed to PostgreSQL to reflect the SQL query capability.
After this, many people refered to it as Postgres since it's less prone to confusion. Supabase is all about
After this, many people refereed to it as Postgres since it's less prone to confusion. Supabase is all about
simplicity, so we also refer to it as Postgres.
<!--
+7 -7
View File
@@ -7,7 +7,7 @@ description: Using the JSON data type in PostgreSQL.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
PostgreSQL supports [JSON functions and operators](https://www.postgresql.org/docs/current/functions-json.html) which gives flexiblity when storing data inside a database column.
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`.
@@ -86,7 +86,7 @@ values={[
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} |
| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} |
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."} |
| 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."} |
</TabItem>
@@ -114,7 +114,7 @@ values
(
'Green Eggs and Ham',
'Dr. Seuss',
'{"description":"Sam has changing food preferences and eats unusally colored food.","price":7.49,"ages":[4,8]}'
'{"description":"Sam has changing food preferences and eats unusually colored food.","price":7.49,"ages":[4,8]}'
),
(
'Harry Potter and the Goblet of Fire',
@@ -147,7 +147,7 @@ values
- 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 unusally colored food."}
- `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`
@@ -181,7 +181,7 @@ const { data, error } = await supabase
{
title:'Green Eggs and Ham',
author:'Dr. Seuss',
metadata: {"description":"Sam has changing food preferences and eats unusally colored food.","price":7.49,"ages":[4,8]}
metadata: {"description":"Sam has changing food preferences and eats unusually colored food.","price":7.49,"ages":[4,8]}
},
{
title:'Harry Potter and the Goblet of Fire',
@@ -228,7 +228,7 @@ console.log(JSON.stringify(data, null, 2));
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} |
| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} |
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."} |
| 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.
@@ -280,7 +280,7 @@ console.log(JSON.stringify(data, null, 2));
| The Poky Little Puppy | Puppy is slower than other, bigger animals. | 5.95 | 3 | 6 |
| The Tale of Peter Rabbit | Rabbit eats some vegetables. | 4.49 | 2 | 5 |
| Tootle | Little toy train has big dreams. | 3.99 | 2 | 5 |
| Green Eggs and Ham | Sam has changing food preferences and eats unusally colored food. | 7.49 | 4 | 8 |
| Green Eggs and Ham | Sam has changing food preferences and eats unusually colored food. | 7.49 | 4 | 8 |
| Harry Potter and the Goblet of Fire | Fourth year of school starts, big drama ensues. | 24.95 | 10 | 99 |
</TabItem>
@@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem';
Every Supabase database is set to UTC timezone by default. We strongly recommend keeping it this way, even if your users are in a different location.
This is becuase it makes it much easier to calculate diffeneces between timezones if you adopt the mental model that "everything in my database is in UTC time".
This is because it makes it much easier to calculate differences between timezones if you adopt the mental model that "everything in my database is in UTC time".
### Change timezone
+1 -1
View File
@@ -41,7 +41,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-realtime.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+1 -1
View File
@@ -50,7 +50,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-create-table-sm.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+1 -1
View File
@@ -18,7 +18,7 @@ Organizations are a way to group your projects. Every Organization can be config
You can invite your Team members into your Organizations so that you can collaborate on projects.
<video width="99%" muted playsInline controls="true">
<source src="/videos/invite-team.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/invite-team.mp4" type="video/mp4" muted playsInline />
</video>
## Projects
+4 -4
View File
@@ -59,7 +59,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/storage/create.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/storage/create.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -122,7 +122,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/storage/upload.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/storage/upload.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -178,7 +178,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/storage/download.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/storage/download.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -231,7 +231,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/storage/policies.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/storage/policies.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+5 -5
View File
@@ -63,11 +63,11 @@ values={[
```sh
1. Go to the "SQL" section.
2. Click "User Management Starter".
4. Click "Run".
3. Click "Run".
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -145,7 +145,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -180,7 +180,7 @@ These variables will be exposed on the browser, and that's completely fine since
export const environment = {
production: false,
supabaseUrl: "YOUR_SUPABASE_URL",
supbaseKey: "YOUR_SUPABASE_KEY"
supabaseKey: "YOUR_SUPABASE_KEY"
};
```
@@ -204,7 +204,7 @@ export class SupabaseService {
private supabase: SupabaseClient;
constructor() {
this.supabase = createClient(environment.supabaseUrl, environment.supbaseKey);
this.supabase = createClient(environment.supabaseUrl, environment.supabaseKey);
}
get user() {
+5 -5
View File
@@ -19,7 +19,7 @@ This example provides the steps to build a simple user management app (from scra
By the end of this guide you'll have an app which allows users to login and update some basic profile details:
<img src="/img/supabase-flutter-demo.png" alt="Supabase User Management example" />
![Supabase User Management example](/img/supabase-flutter-demo.png)
### Github
@@ -57,7 +57,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -131,7 +131,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -411,8 +411,8 @@ class _LoginPageState extends AuthState<LoginPage> {
@override
void initState() {
_emailController = TextEditingController();
super.initState();
_emailController = TextEditingController();
}
@override
@@ -640,7 +640,7 @@ flutter run -d web-server --web-hostname localhost --web-port 3000
And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app.
<img src="/img/supabase-flutter-account-page.png" alt="Supabase User Management example" />
![Supabase User Management example](/img/supabase-flutter-account-page.png)
## Bonus: Profile photos
+2 -2
View File
@@ -75,7 +75,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -155,7 +155,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+3 -3
View File
@@ -71,11 +71,11 @@ values={[
```sh
1. Go to the "SQL" section.
2. Click "User Management Starter".
4. Click "Run".
3. Click "Run".
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -155,7 +155,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+30 -14
View File
@@ -9,6 +9,17 @@ import TabItem from '@theme/TabItem'
## Intro
For the sake of consistency with the other framework Quickstart examples, we'll build a RedwoodJS a little differently than normal.
We **_won't use_** use Prisma to connect to the Supabase Postgres database or [Prisma migrations](https://redwoodjs.com/docs/cli-commands#prisma-migrate) as one typically might in a Redwood app.
Instead, we'll rely on the Supabase client to do some of the work on the **web** side and use the client again on the **api** side to do data fetching as well.
That means, you will want to refrain from running any `yarn rw prisma migrate` commands and also double check your build commands on deployment to ensure Prisma won't reset your database.
:::note
TLDR; Prisma currently doesn't support cross-schema foreign keys, so introspecting the schema fails due to how your Supabase `public` schema references the `auth.users`.
:::
This example provides the steps to build a simple user management app (from scratch!) using Supabase and [RedwoodJS](https://redwoodjs.com/docs/introduction). It includes:
- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data.
@@ -27,7 +38,7 @@ Note: For RedwoodJS apps, port will be 8910
### Github
Whenever you get stuck at any point, take a look at [this repo](https://github.com/dthyresson/redwoodjs-supabase-quickstart).
If you get stuck at any point, take a look at [this repo](https://github.com/dthyresson/redwoodjs-supabase-quickstart).
<!-- ## Video demo
@@ -54,23 +65,23 @@ If you want to do it yourself, let's get started: -->
A Redwood application is split into two parts: a frontend and a backend. This is represented as two node projects within a single monorepo.
The frontend project is called **web** and the backend project is called **api**. For clarity, we will refer to these in prose as **"sides"**, i.e. the "web side" and the "api side".
They are separate projects because code on the web side will end up running in the user's browser while code on the api side will run on a server somewhere.
The frontend project is called **`web`** and the backend project is called **`api`**. For clarity, we will refer to these in prose as **"sides"**, i.e. the "web side" and the "api side".
They are separate projects because code on the `web side` will end up running in the user's browser while code on the `api side` will run on a server somewhere.
:::note
Important: When this guide refers to "API", that means the Supabase API and when it refers to "api side", that means the RedwoodJS api side.
Important: When this guide refers to "API", that means the Supabase API and when it refers to "api side", that means the RedwoodJS `api side`.
:::
The **api side** is an implementation of a GraphQL API. The business logic is organized into "services" that represent their own internal API and can be called both from external GraphQL requests and other internal services.
The **`api side`** is an implementation of a GraphQL API. The business logic is organized into "services" that represent their own internal API and can be called both from external GraphQL requests and other internal services.
The **web side** is built with React. Redwood's router makes it simple to map URL paths to React "Page" components (and automatically code-split your app on each route).
The **`web side`** is built with React. Redwood's router makes it simple to map URL paths to React "Page" components (and automatically code-split your app on each route).
Pages may contain a "Layout" component to wrap content. They also contain "Cells" and regular React components.
Cells allow you to declaratively manage the lifecycle of a component that fetches and displays data.
:::note
FYI: For the sake of consistency with the other framework Quickstart examples, we'll build a RedwoodJS a little differently than normal.
For the sake of consistency with the other framework Quickstart examples, we'll build a RedwoodJS a little differently than normal.
We **_won't use_** use Prisma to connect to the Supabase Postgres database or [Prisma migrations](https://redwoodjs.com/docs/cli-commands#prisma-migrate) as one typically might in a Redwood app.
Instead, we'll rely on the Supabase client to do some of the work on the **web** side and use the client again on the **api** side to do data fetching as well.
Instead, we'll rely on the Supabase client to do some of the work on the **`web`** side and use the client again on the **`api`** side to do data fetching as well.
:::
## Project set up
@@ -79,7 +90,7 @@ Before we start building we're going to set up our Database and API. This is as
and then creating a "schema" inside the database.
:::note
Note: When setting up Supabase, you'll interact with your project dashboard. However, most of the RedwoodJS setup steps will interact with the [Redwood CLI](https://redwoodjs.com/docs/cli-commands) to generate routes, pages, components and more.
When setting up Supabase, you'll interact with your project dashboard. However, most of the RedwoodJS setup steps will interact with the [Redwood CLI](https://redwoodjs.com/docs/cli-commands) to generate routes, pages, components and more.
So be sure to have a terminal at the ready and in your project directory.
:::
@@ -110,7 +121,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -168,6 +179,12 @@ create policy "Anyone can upload an avatar."
</TabItem>
</Tabs>
#### Important Note about Prisma and Migrations
:::note
Because this Quick Start does not use Prisma to manage the database schema, seed it, or run mgrations, you **need** to take extra care when running some of the typical Redwood CLI commands.
:::
### Get the API Keys
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
@@ -188,7 +205,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
@@ -199,7 +216,7 @@ values={[
Let's start building the RedwoodJS app from scratch.
:::note
**Note:** RedwoodJS requires Node.js (=14.x) and Yarn (>=1.15).
RedwoodJS requires Node.js (>=14.x <=16.x) and Yarn (>=1.15).
:::
Make sure you have installed yarn since RedwoodJS relies on it to [manage its packages in workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) for its `web` and `api` "sides".
@@ -236,7 +253,6 @@ yarn redwood setup auth supabase
When prompted:
:::note
Overwrite existing /api/src/lib/auth.[jt]s?
:::
@@ -264,7 +280,7 @@ SUPABASE_KEY=YOUR_SUPABASE_ANON_KEY
SUPABASE_JWT_SECRET=YOUR_SUPABASE_JWT_SECRET
```
And finally, you will also need to save **just** the web side environment variables to the `redwood.toml`.
And finally, you will also need to save **just** the `web side` environment variables to the `redwood.toml`.
```bash title="redwood.toml"
[web]
+3 -3
View File
@@ -53,11 +53,11 @@ values={[
```sh
1. Go to the "SQL" section.
2. Click "User Management Starter".
4. Click "Run".
3. Click "Run".
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -137,7 +137,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+3 -3
View File
@@ -53,11 +53,11 @@ values={[
```sh
1. Go to the "SQL" section.
2. Click "User Management Starter".
4. Click "Run".
3. Click "Run".
```
<video width="99%" muted playsInline controls="true">
<source src="/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>
</TabItem>
@@ -137,7 +137,7 @@ values={[
```
<video width="99%" muted playsInline controls="true">
<source src="/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
</video>
</TabItem>
+11 -9
View File
@@ -8,10 +8,11 @@ module.exports = {
title: 'Supabase',
tagline: 'The open source Firebase alternative.',
url: 'https://supabase.io',
baseUrl: '/',
baseUrl: '/docs/',
favicon: '/favicon.ico',
organizationName: 'supabase', // Usually your GitHub org/user name.
projectName: 'supabase', // Usually your repo name.
projectName: 'Supabase Docs', // Usually your repo name.
onBrokenLinks: 'ignore',
themeConfig: {
colorMode: {
// "light" | "dark"
@@ -56,8 +57,9 @@ module.exports = {
items: [
{
label: 'Overview',
to: '/docs',
activeBaseRegex: '(^/docs$)|(/docs/faq)|(^/docs/guides/examples)',
to: '/',
activeBaseRegex:
'.*.docs/$|^/docs/architecture|(^/docs/guides/(database|auth|storage|api|examples!))|(^/docs/guides/(examples|with-angular|with-flutter|with-nextjs|with-react|with-redwoodjs|with-svelte|with-vue-3)|^/docs/faq|^/docs/going-into-prod|^/docs/handbook|^/docs/company)',
position: 'left',
},
{
@@ -160,10 +162,10 @@ module.exports = {
label: 'RSS',
href: 'https://supabase.io/rss.xml',
},
// {
// label: "Discord",
// href: "https://discordapp.com/invite/docusaurus"
// }
{
label: 'Discord',
href: 'https://discord.supabase.com',
},
],
},
{
@@ -184,7 +186,7 @@ module.exports = {
'@docusaurus/preset-classic',
{
docs: {
// sidebarCollapsible: true,
routeBasePath: '/',
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/supabase/supabase/edit/master/web',
},
+1
View File
@@ -94,6 +94,7 @@ module.exports = {
items: [
'guides/database/introduction',
'guides/database/tables',
'guides/database/functions',
'guides/database/full-text-search',
// 'guides/database/json',
// 'guides/database/arrays',
+88 -64
View File
@@ -2142,7 +2142,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2357,7 +2357,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2489,7 +2489,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2758,7 +2758,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3037,6 +3037,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
@@ -3264,7 +3272,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3484,7 +3492,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3868,7 +3876,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -4078,7 +4086,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -4462,7 +4470,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -16352,6 +16360,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
@@ -20660,7 +20676,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 100,
"line": 102,
"character": 8
}
],
@@ -20690,7 +20706,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 98,
"line": 100,
"character": 10
}
],
@@ -20720,7 +20736,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 96,
"line": 98,
"character": 6
}
],
@@ -20750,7 +20766,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 101,
"line": 103,
"character": 6
}
],
@@ -20780,7 +20796,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 103,
"line": 105,
"character": 10
}
],
@@ -20815,7 +20831,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 94,
"line": 96,
"character": 30
}
]
@@ -20840,7 +20856,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 22,
"line": 24,
"character": 14
}
],
@@ -20864,7 +20880,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 30,
"line": 32,
"character": 12
}
],
@@ -20897,7 +20913,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 26,
"line": 28,
"character": 12
}
],
@@ -20927,7 +20943,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 21,
"line": 23,
"character": 16
}
],
@@ -20957,7 +20973,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 31,
"line": 33,
"character": 15
}
],
@@ -20986,7 +21002,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 32,
"line": 34,
"character": 12
}
],
@@ -21006,7 +21022,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 33,
"line": 35,
"character": 6
}
],
@@ -21044,7 +21060,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 20,
"line": 22,
"character": 24
}
]
@@ -21072,7 +21088,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 87,
"line": 89,
"character": 10
}
],
@@ -21143,7 +21159,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 87,
"line": 89,
"character": 11
}
]
@@ -21164,7 +21180,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 83,
"line": 85,
"character": 4
}
],
@@ -21187,7 +21203,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 91,
"line": 93,
"character": 13
}
],
@@ -21219,7 +21235,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 91,
"line": 93,
"character": 14
}
]
@@ -21241,7 +21257,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 79,
"line": 81,
"character": 29
}
]
@@ -21267,7 +21283,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 47,
"line": 49,
"character": 13
}
],
@@ -21296,7 +21312,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 37,
"line": 39,
"character": 14
}
],
@@ -21353,7 +21369,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 38,
"line": 40,
"character": 12
}
],
@@ -21384,7 +21400,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 37,
"line": 39,
"character": 15
}
]
@@ -21402,7 +21418,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 44,
"line": 46,
"character": 5
}
],
@@ -21423,7 +21439,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 45,
"line": 47,
"character": 22
}
],
@@ -21453,7 +21469,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 51,
"line": 53,
"character": 14
}
],
@@ -21482,7 +21498,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 50,
"line": 52,
"character": 12
}
],
@@ -21503,7 +21519,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 48,
"line": 50,
"character": 7
}
],
@@ -21533,7 +21549,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 52,
"line": 54,
"character": 20
}
],
@@ -21562,7 +21578,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 36,
"line": 38,
"character": 4
}
],
@@ -21583,7 +21599,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 54,
"line": 56,
"character": 17
}
],
@@ -21613,7 +21629,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 49,
"line": 51,
"character": 7
}
],
@@ -21643,7 +21659,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 53,
"line": 55,
"character": 20
}
],
@@ -21673,7 +21689,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 46,
"line": 48,
"character": 18
}
],
@@ -21703,7 +21719,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 55,
"line": 57,
"character": 6
}
],
@@ -21733,7 +21749,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 56,
"line": 58,
"character": 12
}
],
@@ -21762,7 +21778,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 41,
"line": 43,
"character": 15
}
],
@@ -21809,7 +21825,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 41,
"line": 43,
"character": 16
}
]
@@ -21844,7 +21860,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 35,
"line": 37,
"character": 21
}
]
@@ -21873,7 +21889,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 76,
"line": 78,
"character": 6
}
],
@@ -21906,7 +21922,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 63,
"line": 65,
"character": 7
}
],
@@ -21939,7 +21955,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 71,
"line": 73,
"character": 20
}
],
@@ -21972,7 +21988,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 67,
"line": 69,
"character": 10
}
],
@@ -22006,7 +22022,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 59,
"line": 61,
"character": 31
}
]
@@ -22032,7 +22048,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 107,
"line": 109,
"character": 7
}
],
@@ -22062,7 +22078,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 109,
"line": 111,
"character": 10
}
],
@@ -22092,7 +22108,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 108,
"line": 110,
"character": 7
}
],
@@ -22122,7 +22138,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 112,
"line": 114,
"character": 10
}
],
@@ -22144,7 +22160,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 110,
"line": 112,
"character": 14
}
],
@@ -22179,7 +22195,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 106,
"line": 108,
"character": 32
}
]
@@ -22204,7 +22220,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 116,
"line": 118,
"character": 7
}
],
@@ -22224,7 +22240,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 117,
"line": 119,
"character": 7
}
],
@@ -22247,7 +22263,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 115,
"line": 117,
"character": 32
}
]
@@ -22263,7 +22279,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 13,
"line": 15,
"character": 27
}
],
@@ -22350,6 +22366,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
+1 -1
View File
@@ -637,7 +637,7 @@ pages:
subscribe():
description: |
Subscribe to realtime changes in your databse.
Subscribe to realtime changes in your database.
title: 'on().subscribe()'
notes: |
- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime).
+71 -55
View File
@@ -7257,6 +7257,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
@@ -11565,7 +11573,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 100,
"line": 102,
"character": 8
}
],
@@ -11595,7 +11603,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 98,
"line": 100,
"character": 10
}
],
@@ -11625,7 +11633,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 96,
"line": 98,
"character": 6
}
],
@@ -11655,7 +11663,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 101,
"line": 103,
"character": 6
}
],
@@ -11685,7 +11693,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 103,
"line": 105,
"character": 10
}
],
@@ -11720,7 +11728,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 94,
"line": 96,
"character": 30
}
]
@@ -11745,7 +11753,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 22,
"line": 24,
"character": 14
}
],
@@ -11769,7 +11777,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 30,
"line": 32,
"character": 12
}
],
@@ -11802,7 +11810,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 26,
"line": 28,
"character": 12
}
],
@@ -11832,7 +11840,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 21,
"line": 23,
"character": 16
}
],
@@ -11862,7 +11870,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 31,
"line": 33,
"character": 15
}
],
@@ -11891,7 +11899,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 32,
"line": 34,
"character": 12
}
],
@@ -11911,7 +11919,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 33,
"line": 35,
"character": 6
}
],
@@ -11949,7 +11957,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 20,
"line": 22,
"character": 24
}
]
@@ -11977,7 +11985,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 87,
"line": 89,
"character": 10
}
],
@@ -12048,7 +12056,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 87,
"line": 89,
"character": 11
}
]
@@ -12069,7 +12077,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 83,
"line": 85,
"character": 4
}
],
@@ -12092,7 +12100,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 91,
"line": 93,
"character": 13
}
],
@@ -12124,7 +12132,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 91,
"line": 93,
"character": 14
}
]
@@ -12146,7 +12154,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 79,
"line": 81,
"character": 29
}
]
@@ -12172,7 +12180,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 47,
"line": 49,
"character": 13
}
],
@@ -12201,7 +12209,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 37,
"line": 39,
"character": 14
}
],
@@ -12258,7 +12266,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 38,
"line": 40,
"character": 12
}
],
@@ -12289,7 +12297,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 37,
"line": 39,
"character": 15
}
]
@@ -12307,7 +12315,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 44,
"line": 46,
"character": 5
}
],
@@ -12328,7 +12336,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 45,
"line": 47,
"character": 22
}
],
@@ -12358,7 +12366,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 51,
"line": 53,
"character": 14
}
],
@@ -12387,7 +12395,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 50,
"line": 52,
"character": 12
}
],
@@ -12408,7 +12416,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 48,
"line": 50,
"character": 7
}
],
@@ -12438,7 +12446,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 52,
"line": 54,
"character": 20
}
],
@@ -12467,7 +12475,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 36,
"line": 38,
"character": 4
}
],
@@ -12488,7 +12496,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 54,
"line": 56,
"character": 17
}
],
@@ -12518,7 +12526,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 49,
"line": 51,
"character": 7
}
],
@@ -12548,7 +12556,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 53,
"line": 55,
"character": 20
}
],
@@ -12578,7 +12586,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 46,
"line": 48,
"character": 18
}
],
@@ -12608,7 +12616,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 55,
"line": 57,
"character": 6
}
],
@@ -12638,7 +12646,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 56,
"line": 58,
"character": 12
}
],
@@ -12667,7 +12675,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 41,
"line": 43,
"character": 15
}
],
@@ -12714,7 +12722,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 41,
"line": 43,
"character": 16
}
]
@@ -12749,7 +12757,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 35,
"line": 37,
"character": 21
}
]
@@ -12778,7 +12786,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 76,
"line": 78,
"character": 6
}
],
@@ -12811,7 +12819,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 63,
"line": 65,
"character": 7
}
],
@@ -12844,7 +12852,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 71,
"line": 73,
"character": 20
}
],
@@ -12877,7 +12885,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 67,
"line": 69,
"character": 10
}
],
@@ -12911,7 +12919,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 59,
"line": 61,
"character": 31
}
]
@@ -12937,7 +12945,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 107,
"line": 109,
"character": 7
}
],
@@ -12967,7 +12975,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 109,
"line": 111,
"character": 10
}
],
@@ -12997,7 +13005,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 108,
"line": 110,
"character": 7
}
],
@@ -13027,7 +13035,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 112,
"line": 114,
"character": 10
}
],
@@ -13049,7 +13057,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 110,
"line": 112,
"character": 14
}
],
@@ -13084,7 +13092,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 106,
"line": 108,
"character": 32
}
]
@@ -13109,7 +13117,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 116,
"line": 118,
"character": 7
}
],
@@ -13129,7 +13137,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 117,
"line": 119,
"character": 7
}
],
@@ -13152,7 +13160,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 115,
"line": 117,
"character": 32
}
]
@@ -13168,7 +13176,7 @@
"sources": [
{
"fileName": "lib/types.ts",
"line": 13,
"line": 15,
"character": 27
}
],
@@ -13255,6 +13263,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
+17 -9
View File
@@ -2139,7 +2139,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2354,7 +2354,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2486,7 +2486,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -2755,7 +2755,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3034,6 +3034,14 @@
{
"type": "stringLiteral",
"value": "twitch"
},
{
"type": "stringLiteral",
"value": "spotify"
},
{
"type": "stringLiteral",
"value": "slack"
}
]
}
@@ -3261,7 +3269,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3481,7 +3489,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -3865,7 +3873,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -4075,7 +4083,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
@@ -4459,7 +4467,7 @@
"types": [
{
"type": "reference",
"name": "Error"
"name": "ApiError"
},
{
"type": "intrinsic",
+37 -2
View File
@@ -150,17 +150,35 @@ pages:
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key")
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')
```
- name: With additional parameters
js: |
```js
import { createClient } from '@supabase/supabase-js'
const options = { }
const options = {
schema: 'public',
headers: { 'x-my-custom-header': 'my-app-name' },
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true
}
const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key", options)
```
- name: API schemas
js: |
```js
import { createClient } from '@supabase/supabase-js'
const options = { schema: 'other_schema' }
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', options)
```
By default the API server points to the `public` schema. You can enable others database schemas within the Dashboard.
Go to `Settings > API > Schema` and add the schema which you want to expose to on the API.
Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema.
Generating Types:
description: |
Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript through a third-party tool.
@@ -307,6 +325,23 @@ pages:
password: 'example-password',
})
```
- name: Sign up with additional user meta data.
isSpotlight: true
js: |
```js
const { user, session, error } = await supabase.auth.signUp(
{
email: 'example@email.com',
password: 'example-password',
},
{
data: {
first_name: 'John',
age: 27,
}
}
)
```
- name: Sign up with third-party providers.
hideCodeBlock: true
description: |
+4
View File
@@ -1315,4 +1315,8 @@ h4.method-list-item-label .method-list-item-validation {
font-family: 'office code pro';
border: 1px solid var(--custom-border-color);
padding: 2px 6px;
}
details summary:hover {
cursor: pointer;
}
@@ -1,3 +1,14 @@
/*
*
* please note:
*
* This file was renamed from 'index' so the docs/about page
* can be properly served as the homepage
*
* @MildTomato
*
*/
import React, { useState } from 'react'
import clsx from 'clsx'
import Layout from '@theme/Layout'
-7
View File
@@ -1,7 +0,0 @@
{
"rewrites": [
{ "source": "/", "destination": "https://www-internal.supabase.io/new" },
{ "source": "/beta", "destination": "https://www-internal.supabase.io/new/beta" }
],
"trailingSlash": false
}
+6 -6
View File
@@ -4,11 +4,9 @@
This is a single repository for two different websites. Our documents were created with docusaurus and are stored in the web folder. Our beta website can be found in the www folder. This is a standard Next.js website.
The beta website has a `basePath` of `new` and is built with `vercel.json`. This is done to distinguish between HTTP requests from both websites. Any request with a path that begins with `/new/` will be routed to the beta website.
Install the [Vercel CLI](https://vercel.com/cli).
To execute this locally, run the following commands. This will launch the website at http://localhost:8080/, and requests will be automatically proxied (through vercel rewrites) to the docs website (running at http://localhost:3005/) and the beta website (running at http://localhost:3000).
You will need to run the marketing website and docs website seperately.
```
# tab 1
@@ -27,10 +25,12 @@ npm run gen:supabase
npm run start
```
In production, this setup is deployed as three different vercel websites (`docs`, `www` and `main`).
In production, this setup is deployed as two different vercel websites (`docs` and `www`)
## Known issues
- Some hardcoding of `/new` in `www`. Should be fine as long as the basePath doesn't change.
- Referencing resources in nested folders may not work for `web` (eg `/web/static/folder/nestedfolder/asset`) may not work.
- Don't use `Link` since that adds `/new` to the links. Use plain `a` tags when possible.
- Possibly need to prepend all images/assets in docs site with baseUrl.
<!-- // we need to check this -->
<!-- - Don't use `Link` since that adds `/new` to the links. Use plain `a` tags when possible. -->
@@ -25,15 +25,15 @@ Before we get into the details, here are some high-level numbers for the week fo
We had 30,000 new website visitors to [supabase.io](http://supabase.io):
![This graph shows the traffic to our website, that peaks at 15,000 the first day and tails off throughout the week. We had a total of 30,000 visitors to our site. That's according to Google Analytics though, and everyone on HN blocks GA so who knows what the real number is.](/new/images/blog/supabase-traffic-may.png)
![This graph shows the traffic to our website, that peaks at 15,000 the first day and tails off throughout the week. We had a total of 30,000 visitors to our site. That's according to Google Analytics though, and everyone on HN blocks GA so who knows what the real number is.](/images/blog/supabase-traffic-may.png)
<br />
We had over 1400 signups in 7 days:
![This graph shows our signups. Before the launch we had around 100 signups. After the launch it sky-rocketed to 600 in the first day, 900 by the second, and 1000 by the third day. By the end of the week we had over 1400 signups.](/new/images/blog/hn-launch.png)
![This graph shows our signups. Before the launch we had around 100 signups. After the launch it sky-rocketed to 600 in the first day, 900 by the second, and 1000 by the third day. By the end of the week we had over 1400 signups.](/images/blog/hn-launch.png)
Github stars rocketed for our two main repos, [supabase](https://github.com/supabase/supabase) and [realtime](https://github.com/supabase/realtime).
![This graph shows our github stars. It's basically a vertical line. Our main repo went from 300 stars to 1300 overnight.](/new/images/blog/supabase-github-stars-june.png)
![This graph shows our github stars. It's basically a vertical line. Our main repo went from 300 stars to 1300 overnight.](/images/blog/supabase-github-stars-june.png)
## The good
@@ -43,7 +43,7 @@ Here are the things that survived well.
This was the most surprising survivor. Our middleware was served from a single Ubuntu server with 4 CPUs and 8GB of RAM. This server was running our middleware using `docker-compose up`:
![This image shows in middleware architecture. We used docker-compose to pull up 5 open source tools: Kong, Realtime, PostgREST, PG-API, and PG-BOSS.](/new/images/blog/supabase-middleware-docker.png)
![This image shows in middleware architecture. We used docker-compose to pull up 5 open source tools: Kong, Realtime, PostgREST, PG-API, and PG-BOSS.](/images/blog/supabase-middleware-docker.png)
In case you're wondering why any sane company would use that in production, it's because we weren't planning to launch - the HackerNews post was created by an early GitHub follower, while we were alpha testing, and it was too scary to migrate the middleware while it was servicing the thundering herd. All Supabase projects use the same middleware stack (sans docker-compose), so I guess this counts as as a successful load test.
@@ -77,7 +77,7 @@ Let me start by saying that Digital Ocean have been great for getting up and run
The first sign of problems were the frequent production errors. This is a screenshot of emails from Digital ocean for the month of June.
![This image shows all the emails I was receiving from Digital Ocean. I was receiving an email every other day about servers which needed to be migrated.](/new/images/blog/digital-ocean-emails-errors.png)
![This image shows all the emails I was receiving from Digital Ocean. I was receiving an email every other day about servers which needed to be migrated.](/images/blog/digital-ocean-emails-errors.png)
Each of these emails represents one or more servers that has a critical issue:
+1 -1
View File
@@ -18,7 +18,7 @@ Two months ago a developer discovered Supabase and (unexpectedly) [launched us o
<!--truncate-->
![This image shows all of the top dev tool launches on Hacker news. The most popular is Stripe, with 1249 upvotes, the next popular is Supabase with 1120 upvotes, and third is Fly.io with 626 upvotes.](/new/images/blog/supabase-hn-launch.png)
![This image shows all of the top dev tool launches on Hacker news. The most popular is Stripe, with 1249 upvotes, the next popular is Supabase with 1120 upvotes, and third is Fly.io with 626 upvotes.](/images/blog/supabase-hn-launch.png)
Developers were obviously excited about the prospect of an open source Firebase alternative, but the comments were dominated by one emphatic feature request: Auth.
@@ -56,7 +56,7 @@ You can now enable Email Confirmations for new users. This can be toggled on or
The biggest communty contribution to date, [@thorwebdev](https://twitter.com/thorwebdev) added TypeScript support to Supabase. He even [live streamed the process](https://twitter.com/thorwebdev/status/1292722189788016641).
![This git shows how TypeScript makes it even easier to use Supabase, through VSCode's intellisense.](/new/images/blog/typescript-support.gif)
![This git shows how TypeScript makes it even easier to use Supabase, through VSCode's intellisense.](/images/blog/typescript-support.gif)
### Kaizen
@@ -70,7 +70,7 @@ We have a number of small improvements:
The release of Auth last month accelerated our community growth, based on [Orbit Levels.](https://github.com/orbit-love/orbit-model)
![This image shows our community growth. In August we had about 250 active members across GitHub and Twitter.](/new/images/blog/community-august.png)
![This image shows our community growth. In August we had about 250 active members across GitHub and Twitter.](/images/blog/community-august.png)
- We received our first enterprise sponsor. Thanks to [@briannekimmel](https://twitter.com/briannekimmel) from [@WorkLifeVC](https://twitter.com/WorkLifeVC) for becoming an [Enterprise Sponsor](https://github.com/sponsors/supabase).
- [@amorriscode](https://github.com/amorriscode) added Redwood support! [[Pull Request](https://github.com/redwoodjs/redwood/pull/1033)]
@@ -51,7 +51,7 @@ Tune in to our online events.
We've created a [GitHub project board](https://github.com/orgs/supabase/projects/5) to keep track of what's happening and can enjoy collaborating and hacking together 🥳
You can contribute to one of the existing `hacktoberfest` issue, or you can grab one of the ideas from the notes in the project board and [open a new issue](https://github.com/supabase/supabase/issues/new/choose) for it. Make sure to tag the newly created issue with the `hacktoberfest` label. This will be important for you to have a chance at getting the limited edition Hacktoberfest T-Shirt. See the [participation rules](https://hacktoberfest.digitalocean.com/details/#rules) for more details.
You can contribute to one of the existing `hacktoberfest` issue, or you can grab one of the ideas from the notes in the project board and [open a new issue](https://github.com/supabase/supabase/issues/choose) for it. Make sure to tag the newly created issue with the `hacktoberfest` label. This will be important for you to have a chance at getting the limited edition Hacktoberfest T-Shirt. See the [participation rules](https://hacktoberfest.digitalocean.com/details/#rules) for more details.
### I'm a Developer
@@ -71,4 +71,4 @@ We'd love to see you at one of our events and have you contribute to Supabase th
## Questions / ideas / feedback?
We'd love to hear it, just [tweet at us](https://twitter.com/supabase), or [open an issue](https://github.com/supabase/supabase/issues/new/choose).
We'd love to hear it, just [tweet at us](https://twitter.com/supabase), or [open an issue](https://github.com/supabase/supabase/issues/choose).
@@ -33,7 +33,7 @@ Watch a full demo:
We've released OAuth logins! You can now enable third-party logins on your app for Bitbucket, GitHub, GitLab, or Google.
![This is a picture of the supabase dashboard with OAuth logins](/new/images/blog/supabase-oauth-logins.png)
![This is a picture of the supabase dashboard with OAuth logins](/images/blog/supabase-oauth-logins.png)
### Clone tables
@@ -63,7 +63,7 @@ The SQL editor now stores your query history in your browser. You can also save
Supabase was given access to [GitHub Discussions](https://github.com/supabase/supabase/discussions)! This is the place for you to ask questions or show off what you've built with Supabase.
![This is a screenshot of our GitHub Discussions, a new feature by GitHub.](/new/images/blog/supabase-github-discussions.png)
![This is a screenshot of our GitHub Discussions, a new feature by GitHub.](/images/blog/supabase-github-discussions.png)
### Kaizen
@@ -84,7 +84,7 @@ Supabase was given access to [GitHub Discussions](https://github.com/supabase/su
There's been [plenty of drama](https://hacktoberfest.digitalocean.com/hacktoberfest-update) during Hacktoberfest, but Supabase is committed to helping new contributors get started with open source. We've already seen a lot of issues closed by new members to our community and first-time contributors. If you're looking for ways to get involved, read our Hacktoberfest [blog post](https://supabase.io/blog/2020/09/11/supabase-hacktoberfest-2020), check our our [live stream](https://www.youtube.com/watch?v=3_xRLTjvEiE&t=60s), and then dive into our [project board](https://github.com/orgs/supabase/projects/5).
![This is an image of our hacktoberfest project board on GitHub.](/new/images/blog/supabase-hacktoberfest-board.png)
![This is an image of our hacktoberfest project board on GitHub.](/images/blog/supabase-hacktoberfest-board.png)
### Coming next
@@ -40,19 +40,19 @@ Check out the [blog post](https://supabase.io/blog/2020/10/30/improved-dx) to le
Although it was only intended to be a temporary feature, the SQL Editor has become one of the most useful features of Supabase. This month we decided to make give it some attention, adding Tabs and making it full-screen. This is the first of many updates, we've got some exciting things planned for the SQL Editor.
![This image shows a SQL Editor with tabs. Originally our SQL editor was very basic, but we're moving towards something very powerful.](/new/images/blog/sql-editor.png)
![This image shows a SQL Editor with tabs. Originally our SQL editor was very basic, but we're moving towards something very powerful.](/images/blog/sql-editor.png)
### Key commands for Power Users
For the heavy table editor users, we've gone ahead and added a bunch of key commands and keyboard shortcuts so you can zip around and manipulate your tables faster than ever.
![This image shows some of the keyboard shortcuts we introduced on the table editor.](/new/images/blog/keyboard-shortcuts.png)
![This image shows some of the keyboard shortcuts we introduced on the table editor.](/images/blog/keyboard-shortcuts.png)
### Magic Links
One of the most requested Auth features was the ability to send magic links that your users can use to log in. You can use this with new or existing users, and alongside passwords or stand alone.
![This image shows a template where developers can edit the magic links email which is sent to their users on sign up.](/new/images/blog/magic-links.png)
![This image shows a template where developers can edit the magic links email which is sent to their users on sign up.](/images/blog/magic-links.png)
### Kaizen
@@ -34,25 +34,25 @@ Watch a full demo:
You can now add users manually from your dashboard.
![This image shows how to invite a new user directly from the dashboard.](/new/images/blog/invite-users.gif)
![This image shows how to invite a new user directly from the dashboard.](/images/blog/invite-users.gif)
### User admin
You can also perform admin functions on existing users - send password reset emails, magic links, and delete users.
![This image shows how to delete a user directly from the dashboard.](/new/images/blog/delete-users.gif)
![This image shows how to delete a user directly from the dashboard.](/images/blog/delete-users.gif)
### Even more powerful SQL Editor
Last month we [announced](/blog/2020/11/02/supabase-alpha-october-2020#more-powerful-sql-editor) an improved SQL Editor, and this month we've taken it even further. The SQL Editor is now a full Monaco editor, like you'd find in VS Code. Build your database directly from the browser.
![This image shows our improved SQL Editor.](/new/images/blog/supabase-monaco-editor.png)
![This image shows our improved SQL Editor.](/images/blog/supabase-monaco-editor.png)
### Status page
We added a [Status Page](https://status.supabase.io/) which tracks the uptime and latency of the Supabase platform.
![This image shows our new status page.](/new/images/blog/status-page.png)
![This image shows our new status page.](/images/blog/status-page.png)
### Kaizen
+2 -2
View File
@@ -23,7 +23,7 @@ Learn how Monitoro was able to build fast, ensure reliability, and keep scaling
In one month, Monitoro scaled from nothing to nearly one million API requests per day.
![This image Monitoro's API requests every day for a month. They went from zero to 800 thousand daily requests.](/new/images/blog/monitoro-requests.png)
![This image Monitoro's API requests every day for a month. They went from zero to 800 thousand daily requests.](/images/blog/monitoro-requests.png)
### Customer discovery to development
@@ -39,7 +39,7 @@ Within a couple of days, the team had a version ready they could deploy. Monitor
Fast forward to today, and Monitoro's user base has been ramping up, as they use Monitoro to monitor changes to websites all over the world. Despite how fast their user base has grown, the Monitoro team have peace of mind as they scale because they used Supabase, knowing it will just work without worrying about DevOps.
![Quote from Omar - Supabase was exactly the solution I needed so when I saw it on Hacker News I was instantly excited. Supabase allowed us to go further, faster, with our product functionality. We had a fast-growing user base which would have been challenging to support without being able to depend on Supabase.](/new/images/blog/omar-monitoro.png)
![Quote from Omar - Supabase was exactly the solution I needed so when I saw it on Hacker News I was instantly excited. Supabase allowed us to go further, faster, with our product functionality. We had a fast-growing user base which would have been challenging to support without being able to depend on Supabase.](/images/blog/omar-monitoro.png)
### Prototype fast, and keep going
+2 -2
View File
@@ -21,7 +21,7 @@ date: '12-02-2020'
Sarup's background is in open-source, web frontends, and devtools. In the summer of 2020, he was rapidly building MVPs as he explored different problem spaces. Sarup found that reusing his frontend work across projects, wasn't as simple as he'd have liked.
![This image shows a quote from Sarup - Frontends should be as simple as: Sign-up, drag & drop, publish.](/new/images/blog/sarup-tayfa.png)
![This image shows a quote from Sarup - Frontends should be as simple as: Sign-up, drag & drop, publish.](/images/blog/sarup-tayfa.png)
- Zero to MVP: **7 Days**
- Idea to 1st Payment: **30 Days**
@@ -39,7 +39,7 @@ One option was to do it the "old-school" way: Postgres on a custom server, or Mo
Luckily, Sarup discovered Supabase through the Vercel community. Open-source and built on top of Postgres, it was perfect for his future self-hosting needs and also offered him an API out of the box. The current version of TAYFA is the third iteration, and also takes advantage of Supabase Auth, an out of the box auth layer.
![This image shows a quote from his customers - The speed at which TAYFA is evolving is crazy. I've seen ideas translate into live features 10 minutes after speaking on the phone.](/new/images/blog/tanmai-tayfa.png)
![This image shows a quote from his customers - The speed at which TAYFA is evolving is crazy. I've seen ideas translate into live features 10 minutes after speaking on the phone.](/images/blog/tanmai-tayfa.png)
> _"If my product helps customers move fast, then I need to move fast._
>
@@ -20,7 +20,7 @@ date: '12-02-2020'
We are proud to announce we are teaming up with fellow YC Summer 20 Alumni [Strive School](https://strive.school/), to help teach the next generation of software developers about open source software development.
![Supabase and Strive are partnering up to teach OSS.](/new/images/blog/strive-supabase.png)
![Supabase and Strive are partnering up to teach OSS.](/images/blog/strive-supabase.png)
Strive School is on a mission to train the next generation of Computer Engineers, starting from Europe.
@@ -27,11 +27,11 @@ There was some low-hanging fruit to improve performance, but we had one importan
Our dashboard is JavaScript heavy, so we started by setting up analytics to track our bundle sizes. [Next-bundle-analyzer](https://www.npmjs.com/package/@next/bundle-analyzer) (or [webpack-bundle-analyzer](https://www.npmjs.com/package/webpack-bundle-analyzer)) provides an interactive treemap of your generated JavaScript bundles. This is our treemap when we started. It gave us a clear indication what changes we needed to achieve the most impact.
![Nextjs tree analyzer](/new/images/blog/blog/nextjs-tree-analyzer.png)
![Nextjs tree analyzer](/images/blog/blog/nextjs-tree-analyzer.png)
There are some great tools when it comes to Real User Monitoring (RUM). We chose the newly-launched [Sentry performance monitoring](https://sentry.io/for/performance/) product since we already use Sentry for error tracking and we wanted to minimize new tools in our stack. It also supports reporting [Core Web Vitals](https://web.dev/vitals/), the performance metrics created by Google to track initial loading performance, responsiveness and visual stability. Core Web Vitals come with recommended target values, giving us clear goals to hit.
![Core Web Vitals](/new/images/blog/blog/core-web-vitals.png)
![Core Web Vitals](/images/blog/blog/core-web-vitals.png)
## Improving our JavaScript bundle size
@@ -45,7 +45,7 @@ We used [Bundlephobia](https://bundlephobia.com/) on our largest modules. This i
We migrated from `Joi` to `ajv` for our schema validation which was 32% smaller. `ajv` was already bundled as a transitive dependency of other modules, making it a no-brainer.
![NPM dependencies](/new/images/blog/blog/npm-dependencies.png)
![NPM dependencies](/images/blog/blog/npm-dependencies.png)
We reverted our [crypto-js](https://github.com/brix/crypto-js) module from version 4.0 to 3.3.0. Version 4.0 [injects more than 400kb code](https://github.com/brix/crypto-js/issues/276) when used in a browser context. The newer version replaces `Math.random` with node's implementation, injecting the entire node crypto module into the browser context. We use `crypto-js` for decrypting user's API keys and so we're not reliant on the randomness of the PRNG. We might move to a dedicated module like [aes-js](https://www.npmjs.com/package/aes-js) in the future since it has a much smaller surface area than `crypto-js` (in terms of security and performance).
@@ -111,7 +111,7 @@ During our transition from Alpha to Beta, performance was one of the important f
With these changes, we have a respectable Core Web Vitals score. This is a snapshot from Sentry with RUM data from the last week. We are within the recommended threshold for all the 3 Web Vitals.
![Sentry results](/new/images/blog/blog/sentry-results.png)
![Sentry results](/images/blog/blog/sentry-results.png)
Our Next.js build output also shows that users download < 200 kb of JavaScript between any two page transitions. We're still improving too - even though we provide a lot of functionality in our dashboard, we will continue to reduce our bundle sizes.
@@ -33,7 +33,7 @@ Watch a full demo:
We spent months working on Performance, Security, and Reliability. Read more on our [Beta Page](https://supabase.io/beta).
![This image shows our Beta Page.](/new/images/blog/blog/dec-beta.png)
![This image shows our Beta Page.](/images/blog/blog/dec-beta.png)
### Improve your docs inline
@@ -80,7 +80,7 @@ We raised $6M from Y Combinator, Mozilla, and Coatue. You can read more on [Tech
- [@ffbass](https://github.com/ffabss) started working on gotrue-java. [Link](https://github.com/supabase/gotrue-java).
- We've grown more than 50% (GitHub star count) since moving into Beta. [Link](https://twitter.com/supabase/status/1345410714836594693)
![This image shows GitHub star growth.](/new/images/blog/blog/dec-starcount.png)
![This image shows GitHub star growth.](/images/blog/blog/dec-starcount.png)
If you want to keep up to date, make sure you [subscribe to our YouTube channel](https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ) or [follow us on Twitter](https://twitter.com/supabase).
@@ -35,49 +35,49 @@ Watch a full demo:
Anyone who has worked with Firebase long enough has become frustrated over the [lack](https://stackoverflow.com/questions/49979714/how-to-get-count-of-documents-in-a-collection) of `count` functionality. This isn't a problem with PostgreSQL! Our libraries now have support for PostgREST's [exact](https://postgrest.org/en/v7.0.0/api.html?highlight=count#exact-count), [planned](https://postgrest.org/en/v7.0.0/api.html?highlight=count#planned-count), and [estimated](https://postgrest.org/en/v7.0.0/api.html?highlight=count#estimated-count) counts. A massive thanks to [@dshukertjr](https://github.com/supabase/postgrest-js/issues/94#event-4210564301) for this adding support to our client library.
![Supabase now supports count functionality](/new/images/blog/blog/postgres-count.png)
![Supabase now supports count functionality](/images/blog/blog/postgres-count.png)
### New Auth Providers
We enabled 2 new Auth providers - Facebook and Azure. Thanks to [@Levet](https://github.com/supabase/gotrue/pull/54) for the Azure plugin, and once again to [Netlify's amazing work](https://github.com/netlify/gotrue/issues/107) with GoTrue to implement Facebook.
![Supabase now supports Azure and Facebook Oauth providers](/new/images/blog/blog/auth-azure-and-facebook.png)
![Supabase now supports Azure and Facebook Oauth providers](/images/blog/blog/auth-azure-and-facebook.png)
### Auth Audit Trail
We have exposed the audit trail directly in the dashboard, as well as the GoTrue logs. Great for security and debugging.
![Supabase exposes the Auth Audit trail on the dashboard](/new/images/blog/blog/auth-audit.png)
![Supabase exposes the Auth Audit trail on the dashboard](/images/blog/blog/auth-audit.png)
### Auth UI widget
In case our Auth endpoints aren't easy enough already, we've built a React [Auth Widget](http://ui.supabase.com/?path=/story/auth-auth--default) for you to drop into your app and to get up-and-running in minutes.
![Supabase has released a React Auth widget](/new/images/blog/blog/auth-widget.png)
![Supabase has released a React Auth widget](/images/blog/blog/auth-widget.png)
### New `auth.email()` function
We added a helper function for extracting the logged in user's email address.
![Supabase added an email function for using with Policies](/new/images/blog/blog/policies-email.png)
![Supabase added an email function for using with Policies](/images/blog/blog/policies-email.png)
### New Regions
Launch your database in London or Sydney!
![Launch your database in London or Sydney](/new/images/blog/blog/regions-london-sydney.png)
![Launch your database in London or Sydney](/images/blog/blog/regions-london-sydney.png)
### Copy rows as Markdown
You can now copy SQL results as Markdown - super useful for adding to blogs and issues.
![Copy query results as markdown](/new/images/blog/blog/countries.gif)
![Copy query results as markdown](/images/blog/blog/countries.gif)
### React server components
If you're excited by React Server components then check out the Supabase + Server Components experimental repo. [https://github.com/supabase/next-server-components](https://github.com/supabase/next-server-components)
![Use supabase with React Server components](/new/images/blog/blog/react-server-components-supabase.png)
![Use supabase with React Server components](/images/blog/blog/react-server-components-supabase.png)
### Learn
@@ -87,7 +87,7 @@ We know that Auth can be a bit daunting when you're just starting out, so we hav
- [Supabase Auth Deep Dive Part 2: Restrict Table Access](https://youtu.be/qY_iQ10IUhs)
- [Supabase Auth Deep Dive Part 3: User Based Access Policies](https://youtu.be/0LvCOlELs5U)
![We released a Auth Video Series](/new/images/blog/blog/supabase-auth-series.png)
![We released a Auth Video Series](/images/blog/blog/supabase-auth-series.png)
### Kaizen
@@ -112,7 +112,7 @@ We know that Auth can be a bit daunting when you're just starting out, so we hav
- The community has made some serious advances on the [Dart](https://github.com/supabase?q=dart&type=&language=), [C#](https://github.com/supabase?q=csharp&type=&language=), [Python](https://github.com/supabase?q=python&type=&language=), and [Kotlin](https://github.com/supabase?q=kotlin&type=&language=) libraries.
- We were one of the fastest growing open source startups in Q4 last year: [Link](https://twitter.com/RunaCapital/status/1351122231791910916)
![This image shows the Supabase GitHub star growth.](/new/images/blog/blog/jan-21-starcount.png)
![This image shows the Supabase GitHub star growth.](/images/blog/blog/jan-21-starcount.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
+4 -4
View File
@@ -18,7 +18,7 @@ Brad Dwyer is the founder of [Roboflow](https://roboflow.com/?ref=supabase), a s
Learn how Brad and Roboflow used Supabase to launch [Paint.wtf](https://paint.wtf), a product which survived traffic generated from the front page of Hacker News, Reddit, and Product Hunt.
![Supabase and Strive are partnering up to teach OSS.](/new/images/blog/roboflow-website.png)
![Supabase and Strive are partnering up to teach OSS.](/images/blog/roboflow-website.png)
## From idea to a launch in a weekend
@@ -30,7 +30,7 @@ Roboflow settled on a straightforward concept: they prompt users to draw an imag
Brad and the team needed a leaderboard to make this idea work. While their first intuition was to use Firebase, it lacks the built-in functionality for counting the number of documents in a collection - a critical function for implementing their leaderboard design.
![Supabase and Strive are partnering up to teach OSS.](/new/images/blog/roboflow-stat.png)
![Supabase and Strive are partnering up to teach OSS.](/images/blog/roboflow-stat.png)
You might export data to BigQuery, or implement an increment function on collection change, however PostgreSQL has great built in support for counting and Brad felt like this would be the perfect opportunity to test out Supabase and get the functionality he needed for the leaderboards to work reliably and without implementing add-ons.
@@ -40,7 +40,7 @@ Brad and the team built the product overnight and launched it on Hacker News. Pa
Over 100K users submitted drawings in a 24 hour span. At this point, Brad knew he had picked the right setup for his leaderboard as even with this massive spike in usage it continued to perform reliably so his users could get accurate and up to date rankings for their submissions.
![Supabase and Strive are partnering up to teach OSS.](/new/images/blog/roboflow-gallery.png)
![Supabase and Strive are partnering up to teach OSS.](/images/blog/roboflow-gallery.png)
Paint.Wtf has continued to get sustained coverage in the media and has continued to pick up new and unexpected use cases. For example, remote teams are using Paint.wtf as part of their daily ice breaker activities during COVID to keep up team social cohesion.
@@ -52,7 +52,7 @@ Paint.Wtf has continued to get sustained coverage in the media and has continued
>
> Brad Dwyer, CTO Roboflow. -->
![Supabase and Strive are partnering up to teach OSS.](/new/images/blog/roboflow-quote.png)
![Supabase and Strive are partnering up to teach OSS.](/images/blog/roboflow-quote.png)
## Ship fast, and carry on scaling
@@ -34,39 +34,39 @@ Watch a full demo:
We've improved the UX of our Dashboard with sidebars in every section, including the Table view, the Auth section, and the SQL Editor.
![Our dashboard has sidebars](/new/images/blog/feb/sidebar-tables.png)
![Our dashboard has sidebars](/images/blog/feb/sidebar-tables.png)
### SQL Autocomplete
Writing SQL just got 10x easier. We added autocomplete to the SQL editor, including table & column suggestions.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/feb/autocomplete.mp4" type="video/mp4" muted playsInline />
<source src="/images/blog/feb/autocomplete.mp4" type="video/mp4" muted playsInline />
</video>
### Auth Redirects
Redirect your users to specific route within your site on [`signIn()`](https://supabase.io/docs/reference/javascript/auth-signin#sign-in-with-redirect) and [`signUp()`](https://supabase.io/docs/reference/javascript/auth-signup#sign-up-with-redirect).
![Redirect your users after sign up](/new/images/blog/feb/auth-redirect.png)
![Redirect your users after sign up](/images/blog/feb/auth-redirect.png)
### Replication management
We added a page to the Database section for managing Postgres Replication. It's still basic, but you can use it to manage your realtime API - choosing which tables are enabled, and which events to send.
![Replication management](/new/images/blog/feb/manage-replication.png)
![Replication management](/images/blog/feb/manage-replication.png)
### Learning Resources
We've released a new [Resources](https://supabase.io/docs/resources) section in our docs, as well as two new Auth modules: [GoTrue Overview](https://supabase.io/docs/learn/auth-deep-dive/auth-gotrue) and [Google OAuth](https://supabase.io/docs/learn/auth-deep-dive/auth-google-oauth).
![Our dashboard has sidebars](/new/images/blog/feb/docs-resources.png)
![Our dashboard has sidebars](/images/blog/feb/docs-resources.png)
### New Region
Launch your database in South Africa.
![Launch your database in South Africa](/new/images/blog/feb/new-region-south-africa.png)
![Launch your database in South Africa](/images/blog/feb/new-region-south-africa.png)
### Kaizen
@@ -82,7 +82,7 @@ One of the community, [@ftonato](https://github.com/ftonato), has built an amazi
[Check it out!](https://github.com/supabase/supabase/tree/master/examples/with-stencil)
![Supabase with Stencil](/new/images/blog/feb/supabase-stencil.png)
![Supabase with Stencil](/images/blog/feb/supabase-stencil.png)
- @kiwicopple on the LogRocket Podcast. [Link](https://podrocket.logrocket.com/9)
- @bdougie Livestream: More Fullstack React w RedwoodJS + Supabase. [Link](https://www.twitch.tv/videos/907698954)
@@ -90,7 +90,7 @@ One of the community, [@ftonato](https://github.com/ftonato), has built an amazi
We hit 6000 GitHub stars on [GitHub](https://github.com/supabase/supabase)
![This image shows the Supabase GitHub star growth.](/new/images/blog/feb/github-stars-feb-2021.png)
![This image shows the Supabase GitHub star growth.](/images/blog/feb/github-stars-feb-2021.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
@@ -100,7 +100,7 @@ We hit 6000 GitHub stars on [GitHub](https://github.com/supabase/supabase)
Waiting for Supabase Storage? Here's a sneak peek for the upcoming Launch Week at the end of March.
![Supabase Storage coming soon](/new/images/blog/feb/supabase-storage.png)
![Supabase Storage coming soon](/images/blog/feb/supabase-storage.png)
### Get started
@@ -51,11 +51,12 @@ create extension if not exists pg_cron;
If you're using Supabase you can also enable it in the Dashboard.
![This image shows that pg_cron is enabled in the Supabase Dashboard](/new/images/blog/supabase-extensions.png)
![This image shows that pg_cron is enabled in the Supabase Dashboard](/images/blog/supabase-extensions.png)
#### Granting access to the extension
If you're planning to use a `non-superuser` role to schedule jobs, ensure that they are granted access to the `cron` schema and its underlying objects beforehand.
```sql
grant usage on schema cron to {{DB user}};
grant all privileges on all tables in schema cron to {{DB user}};
@@ -105,7 +106,7 @@ select
Now when we see that the payload is sent every minute, exactly on the minute.
![This image shows the website that receives our webhook every minute.](/new/images/blog/website-hook.jpeg)
![This image shows the website that receives our webhook every minute.](/images/blog/website-hook.jpeg)
And that's it! We've built a cron webhook. Breaking down the code example above we have 2 key parts:
+1 -1
View File
@@ -21,7 +21,7 @@ Intheloop.dev is a single point of entry for developers to stay up to date on th
Kevin is launching with coverage on three packages - React, Kotlin and Vite. He is also part of the [#buildinpublic](https://twitter.com/search?q=%23buildinpublic&src=typed_query) movement, In The Loop is open-source - you can [check it out on Github](https://github.com/kevcodez/intheloop). Kevin also developed open-source [Gotrue](https://github.com/supabase/gotrue-kt) and [PostgREST](https://github.com/supabase/postgrest-kt) Kotlin clients for Supabase.
![intheloop.dev screenshot](/new/images/blog/intheloop-screenshot.jpg)
![intheloop.dev screenshot](/images/blog/intheloop-screenshot.jpg)
## Sometimes Firebase just isn't enough
+80 -58
View File
@@ -13,22 +13,25 @@ tags:
date: '2021-03-25'
---
Supabase is an open source Firebase alternative. We're on a mission to build an incredible developer experience around
Supabase is an open source Firebase alternative. We're on a mission to build an incredible developer experience around
the world's best open source tools.
To build an amazing developer experience, we need developers to guide us. So after finishing Y Combinator, we took a
deliberate approach to fundraising. We loaded our Seed round with developers, technical founders, and developer advocates:
To build an amazing developer experience, we need developers to guide us. So after finishing Y Combinator, we took a
deliberate approach to fundraising. We loaded our Seed round with developers, technical founders, and developer advocates:
CTOs who have seen scale, community managers, and hackers. We amassed over 20 angel investors - almost all technical.
The Supabase Team is at full capacity preparing for [Launch Week](/blog/2021/03/25/launch-week) and since we're all short on time we decided -
The Supabase Team is at full capacity preparing for [Launch Week](/blog/2021/03/25/launch-week) and since we're all short on time we decided -
why not ask our Angels to write a fundraising post with us?
So here is our unconventional fundraising announcement, written with a few of the Angels of Supabase.
## Mike Krieger (Instagram)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/mike-krieger-supabase.png" alt="Mike Krieger Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/mike-krieger-supabase.png"
alt="Mike Krieger Supabase"
/>
Cofounder & CTO of Instagram. [@mikeyk](https://twitter.com/mikeyk)
@@ -38,8 +41,8 @@ Cofounder & CTO of Instagram. [@mikeyk](https://twitter.com/mikeyk)
#### Why did you invest in Supabase?
Supabase is building tools that are foundational to almost any interactive, modern app, and doing so in a way that's
really aligned with how I think of building tech stacks. For example, choosing Postgres (and deeply understanding
Supabase is building tools that are foundational to almost any interactive, modern app, and doing so in a way that's
really aligned with how I think of building tech stacks. For example, choosing Postgres (and deeply understanding
Postgres' features) as the underlying datastore.
#### Do you write SQL in uppercase or lowercase?
@@ -52,7 +55,7 @@ A website that I built so I could skip out on writing a school paper instead —
#### What's the worst programming error you've ever made?
On launch day for Instagram, the site was down for a good chunk of time because we hadn't set a favicon.ico *and*
On launch day for Instagram, the site was down for a good chunk of time because we hadn't set a favicon.ico _and_
we had Django set up to email us on all errors. Cue storm of email sends every time someone loaded our homepage…and a very unhappy web server.
#### If you could only use one programming language for the rest of your life, what would it be?
@@ -61,15 +64,18 @@ Python — though I am very intrigued by Rust.
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
Stay curious and don't feel like everything you build has to be "the next big thing"; so many times I've worked on a
Stay curious and don't feel like everything you build has to be "the next big thing"; so many times I've worked on a
fun side project or exploration and ended up learning something I applied to more "serious" work.
## Cassidy Williams (Netlify)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/cassidy-williams-supabase.png" alt="Cassidy Williams Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/cassidy-williams-supabase.png"
alt="Cassidy Williams Supabase"
/>
Principal Developer Experience Engineer at Netlify. Outside of that, makes memes, classes, talks, and content for
Principal Developer Experience Engineer at Netlify. Outside of that, makes memes, classes, talks, and content for
developers. [@cassidoo](https://twitter.com/cassidoo)
#### How many hours per week do you spend coding?
@@ -94,7 +100,7 @@ Oh I was a kid, and definitely used it only for CD-ROM games in those dial-up da
#### Would you rather fight 100 duck-sized horses or 1 horse-sized duck?
100 duck-sized horses, because I'm a weakling and could probably do better with the smaller things as long as
100 duck-sized horses, because I'm a weakling and could probably do better with the smaller things as long as
they aren't too organized.
#### If you could only use one programming language for the rest of your life, what would it be?
@@ -105,11 +111,13 @@ Probably JavaScript. It's gotten to that level of power that I could apply it to
Get a calendar you'll actually use and stick to your to-do lists!
## Thorsten Schaeff (Stripe)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/thor-supabase.png" alt="Thorsten Schaeff Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/thor-supabase.png"
alt="Thorsten Schaeff Supabase"
/>
Helps developers grow the GDP of the Internet as a Developer Advocate at Stripe. [@thorwebdev](https://twitter.com/thorwebdev)
@@ -127,7 +135,7 @@ lowercase - I prefer not to scream at my DB.
#### What was the first program you wrote and what was it written with?
My first proper project was probably at uni, building an app to alert wind surfers of great wind conditions.
My first proper project was probably at uni, building an app to alert wind surfers of great wind conditions.
Was built with Python on a Raspberry Pi, jQuery and PhoneGap
#### When was the first time you used a computer and what did you do with it?
@@ -136,7 +144,7 @@ When I was 9 years old my dad signed me up for an HTML summer camp. That's how i
#### Would you rather fight 100 duck-sized horses or 1 horse-sized duck?
I think there's a market for duck-sized horses. Would capture and sell them. Also duck's have some nasty claws,
I think there's a market for duck-sized horses. Would capture and sell them. Also duck's have some nasty claws,
wouldn't be a good idea to make them bigger!
#### If you could only use one programming language for the rest of your life, what would it be?
@@ -145,14 +153,16 @@ I'd do anything and everything in TypeScript if I could!
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
Get involved with and start contributing to open-source. Start creating content about your open-source contributions,
Get involved with and start contributing to open-source. Start creating content about your open-source contributions,
and I'm certain that it will pay off!
## Brian Douglas (GitHub)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/brian-douglas-supabase.png" alt="Brian Douglas Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/brian-douglas-supabase.png"
alt="Brian Douglas Supabase"
/>
Staff Developer Advocate at GitHub. [@bdougieyo](https://twitter.com/bdougieyo)
@@ -162,8 +172,8 @@ Staff Developer Advocate at GitHub. [@bdougieyo](https://twitter.com/bdougieyo)
#### Why did you invest in Supabase?
Supabase is scratching an itch for me as a developer. I see the value of having a manageable database based on SQL,
but I don't only have limited time to code during the week and I don't want that to get sucked into the maintenance
Supabase is scratching an itch for me as a developer. I see the value of having a manageable database based on SQL,
but I don't only have limited time to code during the week and I don't want that to get sucked into the maintenance
and management of that data. I also was a big Firebase fan, and love the developer ergonomics if offered to me as an early user.
#### Do you write SQL in uppercase or lowercase?
@@ -172,27 +182,30 @@ Always uppercase, but don't ask me what the acronym stands for.
#### What was the first program you wrote and what was it written with?
The first function programming was an Android app in Java that was just a picture of a cat. When you pet the cat it purred,
it was part of an Android tutorial when I thought I wanted to be an Android dev. I later got an iPhone and decided to never
The first function programming was an Android app in Java that was just a picture of a cat. When you pet the cat it purred,
it was part of an Android tutorial when I thought I wanted to be an Android dev. I later got an iPhone and decided to never
write Java again when I found Ruby on Rails. I built a Yelp clone for churches, but bailed on that when I took a full time dev role.
#### When was the first time you used a computer and what did you do with it?
My first time using a computer was in second grade and it was to play wolfenstein. We had a computer that we could use in
the office of the apartment complex I grew up in. One of the older kids installed the game and showed the other kids how
My first time using a computer was in second grade and it was to play wolfenstein. We had a computer that we could use in
the office of the apartment complex I grew up in. One of the older kids installed the game and showed the other kids how
to run in from powershell. Probably not the best game to introduce to a 7 year old, but here we are.
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
I would tell them to start with creating short form content every day. It easier to make content on things you just
I would tell them to start with creating short form content every day. It easier to make content on things you just
learned, so do that. It is also easier to get hired when you already have content.
## Justin Gage (Retool)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/justin-gauge-supabase.png" alt="Justin Gage Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/justin-gauge-supabase.png"
alt="Justin Gage Supabase"
/>
Growth at Retool. Writes [a newsletter](https://technically.dev/) that helps people understand software engineering and tech.
Growth at Retool. Writes [a newsletter](https://technically.dev/) that helps people understand software engineering and tech.
[@itunpredictable](https://twitter.com/itunpredictable)
#### How many hours per week do you spend coding?
@@ -201,8 +214,8 @@ It depends – some weeks I’m mostly writing and coordinating, other weeks I
#### Why did you invest in Supabase?
I had been working on the Firebase integration at Retool for a bit, and kept wondering why it was (a) closed source
and (b) NoSQL only. Over the span of a week, something like 5 or 6 of my developer friends asked me what I thought
I had been working on the Firebase integration at Retool for a bit, and kept wondering why it was (a) closed source
and (b) NoSQL only. Over the span of a week, something like 5 or 6 of my developer friends asked me what I thought
about Supabase, so I checked it out – after using the product for a side project, investing was an easy decision.
#### Do you write SQL in uppercase or lowercase?
@@ -217,17 +230,20 @@ SQL (particularly standard Postgres syntax) is the best language on the planet
Eh, I can’t really give advice, I haven’t figured anything out myself yet!
## Iheanyi Ekechukwu (PlanetScale)
<img className="border dark:border-gray-600 rounded" src="/new/images/blog/angels/iheanyi-ekechukwu-supabase.png" alt="Iheanyi Ekechukwu Supabase"/>
<img
className="border dark:border-gray-600 rounded"
src="/images/blog/angels/iheanyi-ekechukwu-supabase.png"
alt="Iheanyi Ekechukwu Supabase"
/>
Senior Software Engineer at PlanetScale. [@kwuchu](https://twitter.com/kwuchu)
#### How do you pronounce your name?
<video width="99%" controls={true}>
<source src="/new/images/blog/angels/kwuchu.mp4" type="video/mp4" playsInline />
<source src="/images/blog/angels/kwuchu.mp4" type="video/mp4" playsInline />
</video>
#### How many hours per week do you spend coding?
@@ -236,7 +252,7 @@ Pretty much, the majority of my week is spent coding. I'd say realistically, aro
#### Why did you invest in Supabase?
The tagline about Supabase being an "open-source Firebase alternative" had me intrigued. As I looked more deeply into
The tagline about Supabase being an "open-source Firebase alternative" had me intrigued. As I looked more deeply into
the product, I was impressed by the well-thought out design and also how easy it is to use the product as well.
#### Do you write SQL in uppercase or lowercase?
@@ -245,8 +261,8 @@ Uppercase.
#### When was the first time you used a computer and what did you do with it?
During summers as a child, my dad would take me to work with him at the community college he taught at. I'd be sitting
in his office while he was in lectures and actually just use his computer to play that 3D Space Pinball game. I think
During summers as a child, my dad would take me to work with him at the community college he taught at. I'd be sitting
in his office while he was in lectures and actually just use his computer to play that 3D Space Pinball game. I think
I was 5 or 6 years old at the time.
#### If you could only use one programming language for the rest of your life, what would it be?
@@ -255,13 +271,16 @@ Honestly, I would probably choose Go. It's a pretty dope language for building o
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
Always be learning. There's so many things to learn as an engineer and the job is constantly about learning new things.
Always be learning. There's so many things to learn as an engineer and the job is constantly about learning new things.
Never settle, never get comfortable, learn as much as you can consistently.
## Zach Waterfield (On Deck)
<img className="border dark:border-gray-600 rounded overflow-hidden" src="/new/images/blog/angels/zach-waterfield-supabase.png" alt="Zach Waterfield Supabase"/>
<img
className="border dark:border-gray-600 rounded overflow-hidden"
src="/images/blog/angels/zach-waterfield-supabase.png"
alt="Zach Waterfield Supabase"
/>
Engineer at OnDeck, Network Leader at Village Global, Founder of Kopa (W19). [@zlwaterfield](https://twitter.com/zlwaterfield)
@@ -271,9 +290,9 @@ Anywhere from 10 to 50 depending on the week
#### Why did you invest in Supabase?
I have many ideas, and spinning up a backend, db, etc., is so daunting, so I started using Firebase, but it was very
frustrating. When I saw Supabase I instantly knew that was the solution. The ability to use Postgres directly from the
client with authentication built-in was a game-changer. I think it could become the go-to that early-stage companies
I have many ideas, and spinning up a backend, db, etc., is so daunting, so I started using Firebase, but it was very
frustrating. When I saw Supabase I instantly knew that was the solution. The ability to use Postgres directly from the
client with authentication built-in was a game-changer. I think it could become the go-to that early-stage companies
build on to simplify their MVPs.
#### Do you write SQL in uppercase or lowercase?
@@ -282,18 +301,21 @@ UPPERCASE
#### When was the first time you used a computer and what did you do with it?
Weirdly enough, I didn't own a computer until I was in grade 12 and didn't learn to code until I was in University.
Weirdly enough, I didn't own a computer until I was in grade 12 and didn't learn to code until I was in University.
I was the only one in a class of 400+ freshman engineers that had never coded before.
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
Network, network, network. Everything I do and all my successes are based on my network. Whether that be from YC, my
Network, network, network. Everything I do and all my successes are based on my network. Whether that be from YC, my
university peers, OnDeck, Twitter, etc. Focus on building your network, and good opportunities will start to pop up.
## Shawn Wang (Temporal)
<img className="border dark:border-gray-600 rounded overflow-hidden object-cover m-0 p-0 " src="/new/images/blog/angels/swyx-supabase.png" alt="Shawn Wang Supabase" />
<img
className="border dark:border-gray-600 rounded overflow-hidden object-cover m-0 p-0 "
src="/images/blog/angels/swyx-supabase.png"
alt="Shawn Wang Supabase"
/>
Head of Developer Experience at Temporal. [@swyx](https://twitter.com/swyx)
@@ -303,7 +325,7 @@ Head of Developer Experience at Temporal. [@swyx](https://twitter.com/swyx)
#### Why did you invest in Supabase?
I was extremely impressed by the founders and love the idea of offering a beautiful, integrated developer experience atop
I was extremely impressed by the founders and love the idea of offering a beautiful, integrated developer experience atop
of proven, scalable, open source foundations.
#### Do you write SQL in uppercase or lowercase?
@@ -312,8 +334,8 @@ Uppercase if formal, lowercase if lazy!
#### What was the first program you wrote and what was it written with?
We had a computer class in middle school and we were assigned to write a pancake stacking program in BASIC. I was really
obsessed by it and was the only person to submit this assignment complete with a graphical user interface (in BASIC!).
We had a computer class in middle school and we were assigned to write a pancake stacking program in BASIC. I was really
obsessed by it and was the only person to submit this assignment complete with a graphical user interface (in BASIC!).
Sadly I didn't see myself as a programmer until 20 years later.
#### If someone wanted to do what you do, what's a piece of advice you'd give them?
@@ -322,9 +344,9 @@ Sadly I didn't see myself as a programmer until 20 years later.
## By the way
We [raised](https://techcrunch.com/2020/12/15/supabase-raises-6m-for-its-open-source-firebase-alternative/) a $6M seed
round led by Coatue, Mozilla, and YC.
We [raised](https://techcrunch.com/2020/12/15/supabase-raises-6m-for-its-open-source-firebase-alternative/) a $6M seed
round led by Coatue, Mozilla, and YC.
Next week is [Launch Week](/blog/2021/03/25/launch-week) and we'll be launching one new thing every day for a week.
Next week is [Launch Week](/blog/2021/03/25/launch-week) and we'll be launching one new thing every day for a week.
[Check it out](/blog/2021/03/25/launch-week)!
[Check it out](/blog/2021/03/25/launch-week)!
+19 -20
View File
@@ -15,29 +15,28 @@ tags:
date: '2021-03-25'
---
When we joined Y Combinator last summer, we spent the entire 3-month program building one (major) feature: Auth.
When we joined Y Combinator last summer, we spent the entire 3-month program building one (major) feature: Auth.
Demo Day gave our team something to rally around. The looming deadline forced us to deliver a lot of complex functionality in a short amount of time.
After we finished YC, we recreated Demo Day conditions internally: we gave ourselves a 3-month timeline to move from Alpha to Beta.
After we finished YC, we recreated Demo Day conditions internally: we gave ourselves a 3-month timeline to move from Alpha to Beta.
It worked wonders. We made [giant leaps forward](https://supabase.io/beta) in the performance, security, and
It worked wonders. We made [giant leaps forward](https://supabase.io/beta) in the performance, security, and
stability of the platform.
The day after our Beta announcement (still high on the adrenaline of the launch) we asked ourselves:
The day after our Beta announcement (still high on the adrenaline of the launch) we asked ourselves:
what's the most ambitious thing we can hope to launch 3 months from now?
We decided not to settle for just one major feature. We wanted to fill an entire week with launches and announcements.
We decided not to settle for just one major feature. We wanted to fill an entire week with launches and announcements.
Looking at the list of features we planned, and with the relatively small team we have, this felt like a hugely ambitious idea.
Looking at the list of features we planned, and with the relatively small team we have, this felt like a hugely ambitious idea.
But after another 3 months of building, we're happy to announce that...
Starting on Monday 29th March, we'll be commencing our Launch Week!
## What to expect
We don't want to spoil the surprise, so for now we'll give you a teaser of what to expect. Come back here each day to see what we launch,
We don't want to spoil the surprise, so for now we'll give you a teaser of what to expect. Come back here each day to see what we launch,
or follow us on twitter to keep up to date: [@supabase](https://twitter.com/supabase) and follow the hashtag [#supalaunchweek](https://twitter.com/hashtag/supalaunchweek).
## Monday: Pricing
@@ -60,7 +59,7 @@ We’re a startup ourselves, so we want to build a sustainable business. Even th
If you aren’t confident in our business model though, we’re open source. You can [host it yourself](https://github.com/supabase/supabase/tree/master/docker). Even better, everything we build is centered around Postgres, so you can pretty much `pgdump` your database and take it to your favorite Postgres platform.
![Supabase Pricing](/new/images/blog/launch-week/bernie-1.png)
![Supabase Pricing](/images/blog/launch-week/bernie-1.png)
## Tuesday: Storage
@@ -68,21 +67,21 @@ If you aren’t confident in our business model though, we’re open source. You
Checkout the launch post here: [Supabase Storage](https://supabase.io/blog/2021/03/30/supabase-storage)
As with anything that we build in Supabase, Storage is fast, secure and scalable. It's integrated well with the rest of the Supabase ecosystem.
As with anything that we build in Supabase, Storage is fast, secure and scalable. It's integrated well with the rest of the Supabase ecosystem.
**Security** 🔒
The authentication is handled by Kong and the authorization policies are implemented via Row Level Security policies in Postgres. This way we didn't have to implement a new language for implementing authorization policies. Check out our blog post for more details on how this works.
The authentication is handled by Kong and the authorization policies are implemented via Row Level Security policies in Postgres. This way we didn't have to implement a new language for implementing authorization policies. Check out our blog post for more details on how this works.
**Performance** ⚡️
Our storage API is a thin layer built with Fastify, a [blazing fast](https://www.fastify.io/benchmarks/) Node.js framework. The security policies are directly evaluated in Postgres. The object explorer in dashboard makes navigation easy even when you have deeply nested folders or millions of objects in your buckets.
Our storage API is a thin layer built with Fastify, a [blazing fast](https://www.fastify.io/benchmarks/) Node.js framework. The security policies are directly evaluated in Postgres. The object explorer in dashboard makes navigation easy even when you have deeply nested folders or millions of objects in your buckets.
**Scalability** 📈
You can use storage for your terabytes of ML training data, e-commerce product gallery, or just your growing collection of JPEGS featuring cat's playing synths in space. You can truly build in a weekend and scale to millions.
![Supabase Storage](/new/images/blog/launch-week/bernie-2.png)
![Supabase Storage](/images/blog/launch-week/bernie-2.png)
## Wednesday: CLI
@@ -98,7 +97,7 @@ Today we launched the Supabase CLI which includes:
Check out the announcement post here: [https://supabase.io/blog/2021/03/31/supabase-cli](https://supabase.io/blog/2021/03/31/supabase-cli)
![Supabase CLI](/new/images/blog/launch-week/bernie-3.png)
![Supabase CLI](/images/blog/launch-week/bernie-3.png)
## Thursday: UI (not an April Fool's joke, we promise)
@@ -112,18 +111,18 @@ And now we're doing what we do best at Supabase and making it open source, so th
Check out the demo and documentation website directly here: [ui.supabase.io](https://ui.supabase.io/)
![Supabase UI](/new/images/blog/launch-week/bernie-4.png)
![Supabase UI](/images/blog/launch-week/bernie-4.png)
## Friday: One more thing
## Friday: One more thing
- 2 April 2021
It's the season finale of Supabase Launchweek! And we have THREE more things to share:
1) [Connection Pooling with PgBouncer](https://supabase.io/blog/2021/04/02/supabase-pgbouncer) - now you can connect directly to your Postgres instance without needing to worry that you'll cap out on connections. Perfect for use with Prisma.
1. [Connection Pooling with PgBouncer](https://supabase.io/blog/2021/04/02/supabase-pgbouncer) - now you can connect directly to your Postgres instance without needing to worry that you'll cap out on connections. Perfect for use with Prisma.
2) [Workflow Engine](https://supabase.io/blog/2021/04/02/supabase-workflows) - Our WIP states language will eventually enable a drag and drop workflow builder like Zapier inside the dashboard. Built with Elixir for scale!
2. [Workflow Engine](https://supabase.io/blog/2021/04/02/supabase-workflows) - Our WIP states language will eventually enable a drag and drop workflow builder like Zapier inside the dashboard. Built with Elixir for scale!
3) supabase.io is now supabase.com - check out our origin story here: [https://supabase.io/blog/2021/04/02/supabase-dot-com](https://supabase.io/blog/2021/04/02/supabase-dot-com)
3. supabase.io is now supabase.com - check out our origin story here: [https://supabase.io/blog/2021/04/02/supabase-dot-com](https://supabase.io/blog/2021/04/02/supabase-dot-com)
![moar](/new/images/blog/launch-week/bernie-5.png)
![moar](/images/blog/launch-week/bernie-5.png)
+1 -1
View File
@@ -75,7 +75,7 @@ What does this mean for you as a developer?
In the next few days, you will see your usage appear in the dashboard with an upgrade button.
Check back throughout the week to see what else we're launching [here](https://supabase.io/new/blog/2021/03/25/launch-week).
Check back throughout the week to see what else we're launching [here](https://supabase.io/blog/2021/03/25/launch-week).
Sign up for the Supabase Beta [here](https://app.supabase.io).
+7 -7
View File
@@ -24,7 +24,7 @@ There are three key components to Supabase Storage:
- Middleware (access and permissions). This consists of an API Server and Postgres.
- Frontend (a nice UI).
![Storage Infrastructure](/new/images/blog/storage/infra.png)
![Storage Infrastructure](/images/blog/storage/infra.png)
The Storage API server sits behind Kong, an API Gateway. It talks to different storage backends like S3, Backblaze, etc to retrieve and store objects.
@@ -40,15 +40,15 @@ As avid Mac users, we've defaulted to using the column-based explorer in Finder
We put in a lot of effort to make sure that the dashboard is fast and easy to navigate with our miller-based column view, allowing you to get to deeply nested folders quickly. If you're a fan of List Views though, don't worry! We have that option available too. The choice is yours.
![Frontend views](/new/images/blog/storage/ph-5.png)
![Frontend views](/images/blog/storage/ph-5.png)
Our File Browser also has a rich preview for a wide set of file types including images, audio, and videos.
![Frontend preview](/new/images/blog/storage/ph-2.png)
![Frontend preview](/images/blog/storage/ph-2.png)
And if you already know the location of a file but want to save a few clicks, you can paste the path into the location bar and navigate to it directly.
![Frontend navigation](/new/images/blog/storage/ph-4.png)
![Frontend navigation](/images/blog/storage/ph-4.png)
## Designing the storage middleware
@@ -84,7 +84,7 @@ Our storage service sits behind [Kong](https://github.com/kong/kong) along with
For Authorization, we wanted to avoid creating a new DSL like Firebase. Instead, we created one where you can write policies in the One True Language - SQL!
![One True Language](/new/images/blog/storage/true-language.png)
![One True Language](/images/blog/storage/true-language.png)
To do this, we leverage Postgres' Row Level Security. We create a table for `buckets` and `objects` inside each Supabase project. These tables are namespaced in a separate schema called `storage`.
@@ -148,9 +148,9 @@ We have intentionally kept the API surface for the storage backend very small, i
You may be itching to get started tinkering around with our new Supabase storage - we have an example app prepared for you right [here](https://github.com/supabase/supabase-js/tree/master/example/next-storage) which simulates a simple context of setting an avatar image for a user. This will help you to get a high level overview of how to use your project's storage with our client library. For greater detail, refer to our storage API documentation [here](https://supabase.io/docs/reference/javascript/storage-createbucket).
![Example app 1](/new/images/blog/storage/ph-7.png)
![Example app 1](/images/blog/storage/ph-7.png)
![Example app 2](/new/images/blog/storage/ph-6.png)
![Example app 2](/images/blog/storage/ph-6.png)
## What's next
+3 -2
View File
@@ -71,7 +71,8 @@ Now that your application is now prepared, you can use Supabase anywhere in your
```jsx
import { createClient } from '@supabase/supabase-js'
const SUPABASE_URL = 'http://localhost:8000'
const SUPABASE_ANON_KEY = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew'
const SUPABASE_ANON_KEY =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew'
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
```
@@ -139,7 +140,7 @@ This is critical for Row Level Security to work with views. For policies to kick
There was a problem in using the [pgAdmin Schema Diff](https://www.pgadmin.org/docs/pgadmin4/development/schema_diff.html) though, it's a GUI-only tool.
![pgadmin diff](/new/images/blog/cli/pgadmin-diff.png)
![pgadmin diff](/images/blog/cli/pgadmin-diff.png)
So we did what we always strive to do - improve existing open source software. We created a CLI mode for the Schema Diff on [our repo](https://github.com/supabase/pgadmin4/blob/cli/web/cli.py). We've also released a [docker image](https://hub.docker.com/r/supabase/pgadmin-schema-diff) for a quick start.
@@ -20,20 +20,20 @@ Most people don’t know this but the Supabase team has a long history of involv
The team were also founding members of the <a href="https://github.com/awalias/guacchain" target="_blank">Guacchain Foundation</a>, an economic experiment in a deflationary-based monetary system, inspired by the fact that Avacados ripen faster when stored together.
NFTs are now capturing the imagination of speculators everywhere, but NFTs as they exist today have a major flaw. We call it the *Copy-Paste Problem*. The Copy-Paste problem is when a token contains a URL to an image hosted on the web, or even on IPFS; there is nothing stopping someone who does not own the token, from heading to that URL, and just downloading the image for themselves.
NFTs are now capturing the imagination of speculators everywhere, but NFTs as they exist today have a major flaw. We call it the _Copy-Paste Problem_. The Copy-Paste problem is when a token contains a URL to an image hosted on the web, or even on IPFS; there is nothing stopping someone who does not own the token, from heading to that URL, and just downloading the image for themselves.
As our latest foray into NFTs we’re announcing <a href="https://buymeth.com/" target="_blank">BuyMeth.com</a>, (Meth = [M]isleading [E]ncrypted [Th]umbnails) an NFT marketplace that solves the copy-paste problem of NFTs today.
As our latest foray into NFTs we’re announcing <a href="https://buymeth.com/" target="_blank">BuyMeth.com</a>, (Meth = [M]isleading [E]ncrypted [Th]umbnails) an NFT marketplace that solves the copy-paste problem of NFTs today.
![Supabase NFT marketplace BuyMeth.com](/new/images/blog/nft/nft-1.png)
![Supabase NFT marketplace BuyMeth.com](/images/blog/nft/nft-1.png)
### How does it work?
Each NFT stores a blurhash representation of a full image, but also a link to the full encrypted version of the image stored on IPFS. The full image is always encrypted with the key of the *current* owner.
Each NFT stores a blurhash representation of a full image, but also a link to the full encrypted version of the image stored on IPFS. The full image is always encrypted with the key of the _current_ owner.
When a sale is initiated i.e. the seller accepts a buyers offer, Metamask re-encrypts the image with the public key of the buyer, and uploads it to IPFS, the url in the NFT is updated and the buyer assigned as the new owner. After the sale, a 1 week challenge period is initiated where the proceeds of the sale are kept in an escrow contract. The buyer can then decrypt the contents of the image, and can run an automated verification function to verify that the image received (when hashed) does indeed produce the publically available blurhash (or thumbnail). If it does not, then the buyer can submit a claim to the sales contract, along with a proof of the invalid file, and claim back the proceeds.
![Most popular NFTs](/new/images/blog/nft/nft-2.png)
![Most popular NFTs](/images/blog/nft/nft-2.png)
As a way to dis-incentivise previous owners of the image to not reveal the original image, we bake in a royalty mechanism, whereby previous owners receive a fraction of the sale price each time, the artwork changes hands.
Despite the undeniable value of such a platform, this announcement is of course an April Fools joke. We are not launching a Supabase NFT platform; but we are [Launching a TON of other stuff this week](https://supabase.io/new/blog/2021/03/25/launch-week).
Despite the undeniable value of such a platform, this announcement is of course an April Fools joke. We are not launching a Supabase NFT platform; but we are [Launching a TON of other stuff this week](https://supabase.io/blog/2021/03/25/launch-week).
+24 -24
View File
@@ -13,33 +13,33 @@ tags:
date: '2021-04-02'
---
*tl;dr* During the next week, we'll be migrating from "supabase.io" to "supabase.com".
_tl;dr_ During the next week, we'll be migrating from "supabase.io" to "supabase.com".
There are no changes required on your end. Your API URLs will remain on "supabase.co", and only our website URLs will change.
There are no changes required on your end. Your API URLs will remain on "supabase.co", and only our website URLs will change.
The rest of this post talks a bit about the origin of the name, but there's nothing important to know.
## SupaWhat?
At the end of 2019 we released a Postgres [Realtime](https://github.com/supabase/realtime) engine on GitHub.
We created this in my previous company after migrating from Firebase to Postgres.
At the end of 2019 we released a Postgres [Realtime](https://github.com/supabase/realtime) engine on GitHub.
We created this in my previous company after migrating from Firebase to Postgres.
It started gaining traction (if you count "GitHub stars" as traction) and so I tapped my friend, [Ant](https://twitter.com/AntWilson),
It started gaining traction (if you count "GitHub stars" as traction) and so I tapped my friend, [Ant](https://twitter.com/AntWilson),
on the shoulder to see if he wanted to build an open source company with me (he was building another start up at the time).
The company we envisaged had Postgres at the core. We searched for every "dot com" we could think of with "base" in the name - hyperbase,
superbase, suprabase, uberbase. It turns out this is what every database start does. We couldn't find any good "dot coms".
The company we envisaged had Postgres at the core. We searched for every "dot com" we could think of with "base" in the name - hyperbase,
superbase, suprabase, uberbase. It turns out this is what every database start does. We couldn't find any good "dot coms".
And so we moved on to "dot io" domains.
Anybody who knows Ant, knows that he [loves memes](https://supabase.io/blog/2021/03/25/launch-week). While we were brainstorming
we found that "supabase.io" was available.
Anybody who knows Ant, knows that he [loves memes](https://supabase.io/blog/2021/03/25/launch-week). While we were brainstorming
we found that "supabase.io" was available.
To be honest, this name wasn't a strong contender, but it served a very important purpose - it was extremely "meme-able" because
it sounds similar to Nikki Minaj's [Super Bass](https://youtu.be/4JipHEz53sU).
To be honest, this name wasn't a strong contender, but it served a very important purpose - it was extremely "meme-able" because
it sounds similar to Nikki Minaj's [Super Bass](https://youtu.be/4JipHEz53sU).
We chose it as a placeholder and found it was, indeed, very funny to send each other Nikki memes while we brainstormed the business.
![Booom booom booom booom](/new/images/blog/nikki-supabase.jpg)
![Booom booom booom booom](/images/blog/nikki-supabase.jpg)
Note to anyone starting a business, don't use a placeholder. You'll never change it.
@@ -49,29 +49,29 @@ Luckily for us, the name [grew on us](https://news.ycombinator.com/item?id=23325
When we joined Y Combinator, they gave this advice:
> Except in unusual circumstances (like [Twitch.tv](http://twitch.tv/)), if you don't have the .com version of your name,
you should probably change it.
> Except in unusual circumstances (like [Twitch.tv](http://twitch.tv/)), if you don't have the .com version of your name,
> you should probably change it.
We decided to try purchasing [supabase.com](http://supabase.com) from the current owner. The YC forums were full of founders
recommending a particular Domain Specialist who would help us negotiate and purchase the domain. The only catch - he would take
a percentage of the purchase price.
We decided to try purchasing [supabase.com](http://supabase.com) from the current owner. The YC forums were full of founders
recommending a particular Domain Specialist who would help us negotiate and purchase the domain. The only catch - he would take
a percentage of the purchase price.
This struck us as odd. The incentives were more aligned to the domain seller than the purchaser.
We're not afraid to roll up our sleeves at Supabase, so we decided we could handle it ourselves.
We were in for a huge surprise. After searching on the (old) [supabase.com](http://supabase.com) website, we found a company address.
And it was literally 100m from my home.
We were in for a huge surprise. After searching on the (old) [supabase.com](http://supabase.com) website, we found a company address.
And it was literally 100m from my home.
Of all the places in the world that the domain could be registered, the owner was within yelling-distance. But we didn't yell. We simply
asked, and after some negotiation, the owner agreed to sell it.
Of all the places in the world that the domain could be registered, the owner was within yelling-distance. But we didn't yell. We simply
asked, and after some negotiation, the owner agreed to sell it.
We were always willing to walk away from the Supabase brand if we needed to, but the price was reasonable for both parties. There really
We were always willing to walk away from the Supabase brand if we needed to, but the price was reasonable for both parties. There really
isn't much more to it than that.
## What's next?
Over the next few weeks, we'll update our domain name across most of the sites. If you're using a Supabase database and API, you're on
Over the next few weeks, we'll update our domain name across most of the sites. If you're using a Supabase database and API, you're on
a ".co" domain so your apps won't be affected at all.
You may also find some [easter eggs](https://twitter.com/AntWilson/status/1354343248098070530) appear ...
You may also find some [easter eggs](https://twitter.com/AntWilson/status/1354343248098070530) appear ...
+30 -31
View File
@@ -14,65 +14,64 @@ tags:
date: '2021-04-02'
---
Javascript Frameworks like [Next.js,](https://nextjs.org/) [Redwood](https://redwoodjs.com/), [Blitz](https://blitzjs.com/), and tools
like [Prisma](https://www.prisma.io/docs/guides/deployment/deployment#pgbouncer) are all moving in one direction. Serverless.
Javascript Frameworks like [Next.js,](https://nextjs.org/) [Redwood](https://redwoodjs.com/), [Blitz](https://blitzjs.com/), and tools
like [Prisma](https://www.prisma.io/docs/guides/deployment/deployment#pgbouncer) are all moving in one direction. Serverless.
Serverless functions work great for developers using the Supabase API because we manage a [PostgREST](https://postgrest.org/en/v7.0.0/)
server for every project. Supabase also provides direct access to the Postgres database, so that developers can connect any tool they want.
Serverless functions work great for developers using the Supabase API because we manage a [PostgREST](https://postgrest.org/en/v7.0.0/)
server for every project. Supabase also provides direct access to the Postgres database, so that developers can connect any tool they want.
Unfortunately, Serverless function don't work well for direct Postgres connections (for reasons we'll discuss soon).
Jamstack developers make up a large portion of the Supabase Community. While we'd love for developers to use PostgREST, we mostly want
developers to use Postgres. This means supporting the tools which they already love.
Jamstack developers make up a large portion of the Supabase Community. While we'd love for developers to use PostgREST, we mostly want
developers to use Postgres. This means supporting the tools which they already love.
So today we are adding [PgBouncer](https://www.pgbouncer.org/), an open source connection pooler for Postgres.
## What is Connection Pooling?
![Connection Pooling](/new/images/blog/bouncer/connection-pool.png)
![Connection Pooling](/images/blog/bouncer/connection-pool.png)
Typically when a client connects to a PostgreSQL database, they need to open and manage their own database connection. With a connection pool,
connections are already opened and available for use. When a client makes a request, they use a connection from the pool. When the transaction
Typically when a client connects to a PostgreSQL database, they need to open and manage their own database connection. With a connection pool,
connections are already opened and available for use. When a client makes a request, they use a connection from the pool. When the transaction
or session is completed the underlying connection is simply returned to the pool and is once again free to be used by another user or application.
### Handling connection surges
In a traditional architecture, middleware servers (e.g. APIs) manage a small number of connection to a Postgres database.
In a traditional architecture, middleware servers (e.g. APIs) manage a small number of connection to a Postgres database.
Essentially, the middleware server is a connection pool.
In a Serverless environment, there is no middleware server to maintain a connection, so they create a **new** connection for
each concurrent request. Since Serverless functions are typically used for bursty workloads, this can end up opening a lot of
In a Serverless environment, there is no middleware server to maintain a connection, so they create a **new** connection for
each concurrent request. Since Serverless functions are typically used for bursty workloads, this can end up opening a lot of
connections to the database and overwhelm your Postgres server.
Connection pools mitigate this. Connections are opened beforehand and recycled across users and applications. What's more,
[connection pools are specialized for this task](https://medium.com/@k.wahome/database-connections-less-is-more-86c406b6fad).
A small number of connections is sufficient to handle demand ten, twenty times its size, or even more. Whenever a new connection
is required it is taken from a pool of open and available connections instead of initializing an entirely new one. This eliminates
Connection pools mitigate this. Connections are opened beforehand and recycled across users and applications. What's more,
[connection pools are specialized for this task](https://medium.com/@k.wahome/database-connections-less-is-more-86c406b6fad).
A small number of connections is sufficient to handle demand ten, twenty times its size, or even more. Whenever a new connection
is required it is taken from a pool of open and available connections instead of initializing an entirely new one. This eliminates
the need to spawn a new process.
## Misconceptions
It's a common misconception that PgBouncer increases the number of connections a Postgres instance can open.
This is not the case. If Postgres is configured for a maximum of 50 connections before connection pooling, it
will still only be able to open 50. Connection pooling simply keeps connections open and idle, ready to accept clients. Nevertheless,
It's a common misconception that PgBouncer increases the number of connections a Postgres instance can open.
This is not the case. If Postgres is configured for a maximum of 50 connections before connection pooling, it
will still only be able to open 50. Connection pooling simply keeps connections open and idle, ready to accept clients. Nevertheless,
as mentioned above, PgBouncer allows your database to be able to handle more than it can without a connection pool.
## Connection "Queuing"
PgBouncer is like a Queue. With regular Postgres, when you hit your connection limit, new connections are rejected. PgBouncer overcomes this
limitation. When all connections in the pool are in-use, it doesn't reject any incoming requests. Instead,
[PgBouncer queues them](https://www.percona.com/blog/2021/02/26/connection-queuing-in-pgbouncer-is-it-a-magical-remedy/) until a
connection is returned to the pool and made available. This doesn't mean connection pooling is a magic bullet. If your clients is
running expensive queries then the connections might take a long time before they are returned to the pool. The natural solution to
PgBouncer is like a Queue. With regular Postgres, when you hit your connection limit, new connections are rejected. PgBouncer overcomes this
limitation. When all connections in the pool are in-use, it doesn't reject any incoming requests. Instead,
[PgBouncer queues them](https://www.percona.com/blog/2021/02/26/connection-queuing-in-pgbouncer-is-it-a-magical-remedy/) until a
connection is returned to the pool and made available. This doesn't mean connection pooling is a magic bullet. If your clients is
running expensive queries then the connections might take a long time before they are returned to the pool. The natural solution to
this is to increase your database resources so that it processes queries faster or PgBouncer can open more connections.
## Using Connection Pooling in Supabase
![Pooling UI](/new/images/blog/bouncer/pooler-supabase.png)
![Pooling UI](/images/blog/bouncer/pooler-supabase.png)
From today, all new projects will include connection pooling. In the `Database` section of our dashboard, you will notice a new section for it.
Under the hood, we utilise PgBouncer which is installed in the same server as PostgreSQL. Through the dashboard, we provide you with the
necessary connection details to start using the connection pool as well as the ability to modify `Pool Mode`. Not sure which mode to use?
From today, all new projects will include connection pooling. In the `Database` section of our dashboard, you will notice a new section for it.
Under the hood, we utilise PgBouncer which is installed in the same server as PostgreSQL. Through the dashboard, we provide you with the
necessary connection details to start using the connection pool as well as the ability to modify `Pool Mode`. Not sure which mode to use?
Below is a quick primer on each mode.
## Pool modes
@@ -95,6 +94,6 @@ This is the most granular option. Connections are returned to the pool after eve
Try out connection pooling now with a new project in the [dashboard.](http://app.supabase.io) For now, we do not have any plans to port this over to older projects.
Eventually, we will expose more PgBouncer settings to the UI such as `Pool Size`. At the moment it is set to `15`.
Eventually, we will expose more PgBouncer settings to the UI such as `Pool Size`. At the moment it is set to `15`.
We are still working towards getting the latest version of Supabase Postgres to both the AWS and Digital Ocean marketplaces. Follow us on [Twitter](https://www.notion.so/PgBouncer-is-now-available-in-Supabase-345a74d402464670923cf404b714a354) to be informed once it's released!
We are still working towards getting the latest version of Supabase Postgres to both the AWS and Digital Ocean marketplaces. Follow us on [Twitter](https://www.notion.so/PgBouncer-is-now-available-in-Supabase-345a74d402464670923cf404b714a354) to be informed once it's released!
+1 -1
View File
@@ -24,7 +24,7 @@ We're not releasing Functions today. Trust us, we know you want them. They are c
But we are building something that we think you're going to like: Workflows. We haven't finished building it yet, but Workflows are
a "piece" of the Function story and arguably an even more exciting feature.
![Everyone wants functions](/new/images/blog/workflows/functions.jpg)
![Everyone wants functions](/images/blog/workflows/functions.jpg)
## Firebase Functions
@@ -28,30 +28,29 @@ Watch a full demo:
allowFullScreen
></iframe>
## Supabase Storage
Need to store images, audio, and video clips? Well now you can do it on [Supabase Storage](https://supabase.io/blog/2021/03/30/supabase-storage). It's backed by S3 and our new [OSS storage API](https://github.com/supabase/storage-api) written in Fastify and Typescript. Read the [full blog post](https://supabase.io/blog/2021/03/30/supabase-storage).
![Supabase Storage](/new/images/blog/storage/ph-1.png)
![Supabase Storage](/images/blog/storage/ph-1.png)
## Connection Pooling
The Supabase API already handles Connection Pooling, but if you're connecting to your database directly (for example, with Prisma) we now [bundle PgBouncer](https://supabase.io/blog/2021/04/02/supabase-pgbouncer). Read the [full blog post](https://supabase.io/blog/2021/04/02/supabase-pgbouncer).
![Connection Pooling](/new/images/blog/bouncer/pgbouncer-thumb.jpg)
![Connection Pooling](/images/blog/bouncer/pgbouncer-thumb.jpg)
## React UI Component Library
We open sourced our internal UI component library, so that anyone can use and contribute to the Supabase aesthetic. It lives at [ui.supabase.io](https://ui.supabase.io/) . It was also the #1 Product of the Day [on Product Hunt](https://www.producthunt.com/posts/supabase-ui).
![React UI Library](/new/images/blog/march-2021/supabase-ui.png)
![React UI Library](/images/blog/march-2021/supabase-ui.png)
## CLI
Now you can run Supabase locally in the terminal with `supabase start`. We have done some preliminary work on [diff-based schema migrations](https://supabase.io/blog/2021/03/31/supabase-cli#migrations), and added some new tooling for self-hosting Supabase with Docker. [Blog post here](https://supabase.io/new/blog/2021/03/31/supabase-cli).
Now you can run Supabase locally in the terminal with `supabase start`. We have done some preliminary work on [diff-based schema migrations](https://supabase.io/blog/2021/03/31/supabase-cli#migrations), and added some new tooling for self-hosting Supabase with Docker. [Blog post here](https://supabase.io/blog/2021/03/31/supabase-cli).
![Supabase CLI](/new/images/blog/march-2021/supabase-cli.png)
![Supabase CLI](/images/blog/march-2021/supabase-cli.png)
## Pricing
@@ -59,30 +58,30 @@ Our most frequently asked question by far is "ok supabase is sweet, but how mu
See [Pricing Page](https://supabase.io/pricing) for full details and also our blog on why [pricing is hard](https://supabase.io/blog/2021/03/29/pricing).
![Supabase Pricing](/new/images/blog/march-2021/supabase-pricing.jpg)
![Supabase Pricing](/images/blog/march-2021/supabase-pricing.jpg)
## NFT Platform
Well... not really, but it made for a great [April Fools joke](https://supabase.io/blog/2021/04/01/supabase-nft-marketplace).
![Supabase NFT marketplace BuyMeth.com](/new/images/blog/nft/nft-1.png)
![Supabase NFT marketplace BuyMeth.com](/images/blog/nft/nft-1.png)
## Supabase Dot Com
We are now dot com! We'll be porting across over the next few weeks. Read the origin story behind the name [here](https://supabase.io/blog/2021/04/02/supabase-dot-com).
![Supabase Dot Com](/new/images/blog/supabase-dot-com-og.jpg)
![Supabase Dot Com](/images/blog/supabase-dot-com-og.jpg)
## OAuth Scopes
Thanks to a comunity contribution ([@_mateomorris](https://twitter.com/_mateomorris) and [@Beamanator](https://twitter.com/Beamanator)), Supabase Auth now includes OAuth scopes. These allow you to request elevated access during login. For example, you may want to request access to a list of Repositories when users log in with GitHub. Check out the [Documentation](https://supabase.io/docs/reference/javascript/auth-signup#sign-up-with-scopes).
Thanks to a comunity contribution ([@\_mateomorris](https://twitter.com/_mateomorris) and [@Beamanator](https://twitter.com/Beamanator)), Supabase Auth now includes OAuth scopes. These allow you to request elevated access during login. For example, you may want to request access to a list of Repositories when users log in with GitHub. Check out the [Documentation](https://supabase.io/docs/reference/javascript/auth-signup#sign-up-with-scopes).
![Oauth Scope](/new/images/blog/march-2021/oauth-scopes.png)
![Oauth Scope](/images/blog/march-2021/oauth-scopes.png)
## Kaizen
- You can now manage your PostgREST configuration inside the Dashboard.
- Our website has been redesigned. Check out our new [Homepage](https://supabase.io/) and [Blog](https://supabase.io/blog), and our new [Database](https://supabase.io/database), [Auth](https://supabase.io/auth), and [Storage](https://supabase.io/storage) product pages.
- Our website has been redesigned. Check out our new [Homepage](https://supabase.io/) and [Blog](https://supabase.io/blog), and our new [Database](https://supabase.io/database), [Auth](https://supabase.io/auth), and [Storage](https://supabase.io/storage) product pages.
- We refactored some of our Filter methods to make them even easier to use. Check out the [Full Text Search](https://supabase.io/docs/reference/javascript/textsearch) refactor.
- We have added several new sections to our Docs including: [Local Dev](https://supabase.io/docs/guides/local-development), [Self Hosting](https://supabase.io/docs/guides/self-hosting), and [Postgres Reference](https://supabase.io/docs/reference/postgres/getting-started) docs (all still under development).
@@ -98,7 +97,7 @@ Thanks to a comunity contribution ([@_mateomorris](https://twitter.com/_mateomor
- Svelte Integration by [Khaerunnisa Isnaeni](https://www.youtube.com/channel/UCqNDj6eQeTLHuEwgEHWOGjw) [[Video](https://www.youtube.com/watch?v=odPYzJJyEJI)]
- An [example app](https://github.com/supabase/supabase/tree/master/examples/nextjs-ts-user-management) for adding User Profiles to your Next.js app
![Supabase Stars march 2021](/new/images/blog/march-2021/supabase-stars-march-2021.png)
![Supabase Stars march 2021](/images/blog/march-2021/supabase-stars-march-2021.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
@@ -112,7 +111,7 @@ Lets say for each new sign up, you want to trigger a slack alert, send them an e
For this we are working on our own [Workflow engine](https://supabase.io/blog/2021/04/02/supabase-workflows), it will eventually have a Zapier-like interface inside the dashboard. For now it's a state-machine interpreter (fully compatible with Amazon States Language) written in Elixir, [open source](https://github.com/supabase/workflows), and ready for community contributions.
![Workflows](/new/images/blog/workflows/workflows-thumb.jpg)
![Workflows](/images/blog/workflows/workflows-thumb.jpg)
### Get started
@@ -12,7 +12,7 @@ tags:
date: '2021-05-05'
---
This month was a "gardening" month for Supabase. The team focused on stability, security, and community support.
This month was a "gardening" month for Supabase. The team focused on stability, security, and community support.
Check out what we were working on below, as well as some incredible Community contributions.
### Quick demo
@@ -33,18 +33,17 @@ Watch a full demo:
We're a developer tool, which means that Dark Mode is [extremely popular](https://twitter.com/supabase/status/1388131942919376904).
![This poll on twitter shows that 78.5% of our developer base use Dark Mode for the IDE](/new/images/blog/april-2021/twitter-darkmode.png)
![This poll on twitter shows that 78.5% of our developer base use Dark Mode for the IDE](/images/blog/april-2021/twitter-darkmode.png)
While Dark mode is great, for some people it's not an option. Dark Mode is difficult to use for developers with astigmatisms,
While Dark mode is great, for some people it's not an option. Dark Mode is difficult to use for developers with astigmatisms,
or even just working in brightly-lit environments.
So today we're shipping Light Mode. Access it in the settings of your [Dashboard](https://app.supabase.io).
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/april-2021/light-mode.mp4" type="video/mp4" muted playsInline />
<source src="/images/blog/april-2021/light-mode.mp4" type="video/mp4" muted playsInline />
</video>
## Translations
With the help of the community, we [started internationalizing](https://github.com/supabase/supabase/issues/1341) our main repository:
@@ -69,60 +68,60 @@ With the help of the community, we [started internationalizing](https://github.c
- [Turkish / Türkçe](https://github.com/supabase/supabase/blob/master/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/supabase/supabase/blob/master/i18n/README.uk.md)
![Map of the world](/new/images/blog/april-2021/map.png)
![Map of the world](/images/blog/april-2021/map.png)
## OpenAPI spec for Storage
We released [Storage Api docs](https://supabase.github.io/storage-api) built using OpenAPI (swagger).
We released [Storage Api docs](https://supabase.github.io/storage-api) built using OpenAPI (swagger).
![Storage API documentation](/new/images/blog/april-2021/storage-openapi.png)
![Storage API documentation](/images/blog/april-2021/storage-openapi.png)
## Stripe Sync Engine (Experimental)
We [open-sourced a server](https://github.com/supabase/stripe-sync-engine) which keeps any Postgres database in sync with Stripe.
This is experimental only. We're evaluating other tools such as [Singer](https://www.singer.io/tap/stripe/postgresql/),
We [open-sourced a server](https://github.com/supabase/stripe-sync-engine) which keeps any Postgres database in sync with Stripe.
This is experimental only. We're evaluating other tools such as [Singer](https://www.singer.io/tap/stripe/postgresql/),
which provide a more general solution (but are less "realtime"), and we're opening it up here to gather feedback.
![Stripe sync engine](/new/images/blog/april-2021/stripe-sync-engine.jpg)
![Stripe sync engine](/images/blog/april-2021/stripe-sync-engine.jpg)
## Community spotlight: Threaded comments
One of the most powerful Postgres features is "recursive CTEs" which can be used for nested items (comments, pages, friend-graphs). [@lawrencecchen](https://twitter.com/lawrencecchen) has built a full [Threaded Comments demo](https://github.com/lawrencecchen/threaded-comments) which you can [Deploy with a single click](https://github.com/lawrencecchen/threaded-comments#instant-deploy). Want to add comments to your blog with [Full Text Search](https://supabase.io/docs/reference/javascript/textsearch)? Just use Postgres.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/april-2021/threaded-small.mp4" type="video/mp4" muted playsInline />
<source src="/images/blog/april-2021/threaded-small.mp4" type="video/mp4" muted playsInline />
</video>
## Community spotlight: SupaScript
It looks like [@burggraf2](https://twitter.com/burggraf2) got tired of waiting for us to ship Functions, and decided to
build a whole JS ecosystem within his Supabase database. If you want to write PG functions in JS, import remote libraries
It looks like [@burggraf2](https://twitter.com/burggraf2) got tired of waiting for us to ship Functions, and decided to
build a whole JS ecosystem within his Supabase database. If you want to write PG functions in JS, import remote libraries
from the web, and console log to your browser, check out this [SupaScript repo](https://github.com/burggraf/SupaScript).
```js
// After installing:
// After installing:
// https://github.com/burggraf/SupaScript#installation
/**
* Get all users who logged in this week.
* Use in the database: select * from users_this_week();
* Use in the browser: supabase.rpc('users_this_week');
*/
*/
create or replace function users_this_week()
returns json as $$
const moment = require('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.js', false);
const lastWeek = moment().subtract(7, 'days');
const query = 'select * from auth.users where created_at > $1'
const users = sql(query, lastWeek);
return users;
return users;
$$ language plv8;
```
## Community spotlight: Fireship
Fireship reviewed Supabase last week, and despite being a (self-proclaimed) Firebase fan-boy, the review was very impartial.
Fireship reviewed Supabase last week, and despite being a (self-proclaimed) Firebase fan-boy, the review was very impartial.
<iframe
className="w-full video-with-border"
@@ -134,24 +133,22 @@ Fireship reviewed Supabase last week, and despite being a (self-proclaimed) Fire
allowFullScreen
></iframe>
## Community
- Watch [@everConfusedGuy](https://twitter.com/everConfusedGuy)'s talk at DevX conf - Building Supabase Storage: [YouTube video](https://www.youtube.com/watch?v=YsUYOsq_o7g)
- DuckDuckAbdaal by [@Nutlope](https://twitter.com/Nutlope) - a personalized search engine: [Twitter](https://twitter.com/Nutlope/status/1389082406477463557)
- Supabase in 6 minutes by [Georges Duverger](https://www.youtube.com/channel/UCNERPJ-vs61KEsD_dRNWFIw): [YouTube video](https://www.youtube.com/watch?v=c8DNV9yl0mg)
- Build a SaaS Platform with Stripe by [@__dijonmusters:](https://twitter.com/_dijonmusters) [DEV blog](https://dev.to/dijonmusters/series/12346)
- Build a SaaS Platform with Stripe by [@\_\_dijonmusters:](https://twitter.com/_dijonmusters) [DEV blog](https://dev.to/dijonmusters/series/12346)
- Supabase & Sveltekit by Svelte Mastery: [YouTube video](https://www.youtube.com/watch?v=j4AV2Liojk0)
- Firebase vs. Supabase - Draftbit Office Hours: [YouTube Livestream](https://www.youtube.com/watch?v=9Yg6i_zCuiM)
**Supabase Github Star Growth**
- Our [main GitHub repo](https://github.com/supabase/supabase) grew 60% (by stars) and we saw a flood of new contributors.
- Our [main GitHub repo](https://github.com/supabase/supabase) grew 60% (by stars) and we saw a flood of new contributors.
- Our [UI Library](https://github.com/supabase/ui) grew 175%
- Our [Realtime Server](https://github.com/supabase/realtime) grew 39% after landing on the [front page of Hacker News](https://news.ycombinator.com/item?id=26968449).
![Stars from github](/new/images/blog/april-2021/stars-all.png)
![Stars from github](/images/blog/april-2021/stars-all.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
@@ -169,7 +166,7 @@ We're also working on our [Workflows engine](https://supabase.io/blog/2021/04/02
[We started hiring](https://supabase.io/docs/careers).
![screenshot of our hiring page](/new/images/blog/april-2021/hiring.png)
![screenshot of our hiring page](/images/blog/april-2021/hiring.png)
### Get started
+14 -16
View File
@@ -1,6 +1,6 @@
---
title: Supabase Beta May 2021
description: Apple & Twitter Logins, Supabase Grid, Go & Swift Libraries.
description: Apple &amp; Twitter Logins, Supabase Grid, Go &amp; Swift Libraries.
author: paul_copplestone
author_url: https://github.com/kiwicopple
author_image_url: https://github.com/kiwicopple.png
@@ -30,55 +30,55 @@ Watch a full demo:
## Apple logins are now available
Did you know: if you ship an app to the App Store with any third-party logins, you're required to enable Apple logins as well? Now you can with Supabase Auth.
Did you know: if you ship an app to the App Store with any third-party logins, you're required to enable Apple logins as well? Now you can with Supabase Auth.
![Apple OAuth is now available in Supabase](/new/images/blog/2021-may/supabase-apple-login.png)
![Apple OAuth is now available in Supabase](/images/blog/2021-may/supabase-apple-login.png)
## Twitter logins are now available
You can also use Twitter as an OAuth provider with Supabase Auth. Twitter has a very archaic OAuth implementation, so this one took awhile.
![Twitter OAuth is now available in Supabase](/new/images/blog/2021-may/supabase-twitter-login.png)
![Twitter OAuth is now available in Supabase](/images/blog/2021-may/supabase-twitter-login.png)
## New storage policy editor
We shipped a new Policy Editor for managing Row Level Security on your Storage. We provide some templates to simplify the process for new developers.
We shipped a new Policy Editor for managing Row Level Security on your Storage. We provide some templates to simplify the process for new developers.
![New Policy Editor](/new/images/blog/2021-may/storage-policies.png)
![New Policy Editor](/images/blog/2021-may/storage-policies.png)
## Supabase Grid
We are still working on Open Sourcing our Dashboard, and took another step closer by publicly releasing a new [Supabase Grid](https://github.com/supabase/grid). It's not ready to use outside of the Supabase ecosystem, but over time we hope to make it usable with any Postgres Database.
![This is an image of the new Supabase Grid](/new/images/blog/2021-may/table-grid.png)
![This is an image of the new Supabase Grid](/images/blog/2021-may/table-grid.png)
## Japan (Tokyo) 🇯🇵 is now available as a region
There are a huge number of Supabase developers in Japan and China, and at their request we've launched Tokyo as a region.
![Tokyo is now availabel as a region](/new/images/blog/2021-may/japan-region.png)
![Tokyo is now availabel as a region](/images/blog/2021-may/japan-region.png)
## Return data as CSV
You can now [retrieve your data](https://supabase.io/docs/reference/javascript/select#return-data-as-csv) as Comma Separated Values. Thanks to [@andreivreja](https://github.com/andreivreja) for the [awesome PR](https://github.com/supabase/postgrest-js/pull/187).
![Download data as a CSV](/new/images/blog/2021-may/return-data-as-csv.png)
![Download data as a CSV](/images/blog/2021-may/return-data-as-csv.png)
## New Go Libraries
The community started developing the Go libraries. [postgrest-go](https://github.com/supabase/postgrest-go) is completed, [@Yusuf_Papurcu](https://twitter.com/Yusuf_Papurcu) and [@muratmirgun](https://twitter.com/muratmirgun) are working on the remaining libraries.
![Supabase Go Libraries](/new/images/blog/2021-may/supabase-go-support.png)
![Supabase Go Libraries](/images/blog/2021-may/supabase-go-support.png)
## New Swift Libraries
The community started developing the Swift libraries too. [@satishbabariya](https://twitter.com/satishbabariya) is making huge progress on
The community started developing the Swift libraries too. [@satishbabariya](https://twitter.com/satishbabariya) is making huge progress on
[`storage-swift`](https://github.com/supabase/storage-swift),
[`gotrue-swift`](https://github.com/supabase/gotrue-swift),
[`realtime-swift`](https://github.com/supabase/realtime-swift), and
[`supabase-swift`](https://github.com/supabase/supabase-swift).
![Supabase Swift Libraries](/new/images/blog/2021-may/supabase-swift-support.png)
![Supabase Swift Libraries](/images/blog/2021-may/supabase-swift-support.png)
## Build in Public
@@ -97,7 +97,6 @@ We started a weekly 1-hour live stream where we build in public.
allowFullScreen
></iframe>
## Community
- `@p_phiri` made his first OSS contribution, and documented it on YouTube. [Twitter](https://twitter.com/p_phiri/status/1397815806990372865?s=20).
@@ -109,9 +108,9 @@ We started a weekly 1-hour live stream where we build in public.
- `@JonoYeong` created a 6-minute overview of Supabase. [YouTube](https://www.youtube.com/watch?v=1F240hR7nHU). [Twitter](https://twitter.com/JonoYeong/status/1398451556723294208).
- Everyone who has produced Supabase content is now receiving their [swag](https://twitter.com/coderinblack/status/1397042488586559490?s=20). Send a link to your blog, app, or video to swag@supabase.io along with your address and we'll make sure you're included in the next drop.
**Supabase Github Star Growth** 
**Supabase Github Star Growth**
![13223 stars on GitHub.](/new/images/blog/2021-may/supabase-stars-may-2021.png)
![13223 stars on GitHub.](/images/blog/2021-may/supabase-stars-may-2021.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
@@ -123,7 +122,6 @@ If you want to keep up to date, make sure you [subscribe to our YouTube channel]
We're planning another Launch Week at the end of July. We'll probably have a quiet month of shipping this month so that we can get everything prepared for July.
### Get started
- Start using Supabase today: [app.supabase.io](https://app.supabase.io/)
+11 -11
View File
@@ -12,22 +12,22 @@ tags:
date: '2021-07-02'
---
PostgreSQL manages permissions through roles. To create these roles, a database user needs the `CREATEROLE` privilege,
PostgreSQL manages permissions through roles. To create these roles, a database user needs the `CREATEROLE` privilege,
which not only allows role creation but also _modification_ of any role (except superusers).
At Supabase, we use dedicated roles for each of our customers' backend services. For instance, our [Storage API](https://supabase.io/storage) 
uses the `supabase_storage_admin` role for connecting to the database. Giving the `CREATEROLE` privilege to our customers would allow them to
uses the `supabase_storage_admin` role for connecting to the database. Giving the `CREATEROLE` privilege to our customers would allow them to
drop this role and take their own Storage API down.
And yet, we want to give our customers the ability to manage roles the same as they do it in on-premises databases,
And yet, we want to give our customers the ability to manage roles the same as they do it in on-premises databases,
with the usual `CREATE ROLE`, `ALTER ROLE`, and `DROP ROLE` statements.
So, how do we grant them the `CREATEROLE` privilege and, at the same time, protect our own roles? In this blog post,
So, how do we grant them the `CREATEROLE` privilege and, at the same time, protect our own roles? In this blog post,
we explain how we managed to do this by using PostgreSQL Hooks in our [SupaUtils](https://github.com/supabase/supautils) extension.
## Reserved Roles
PostgreSQL has a list of [predefined roles](https://www.postgresql.org/docs/14/predefined-roles.html) — all prefixed
PostgreSQL has a list of [predefined roles](https://www.postgresql.org/docs/14/predefined-roles.html) — all prefixed
with "pg\_" — that cannot be dropped or altered. Attempting to do so will throw an error mentioning that the role is "reserved".
```sql
@@ -52,7 +52,7 @@ LOCATION: handle_rename, rdsutils.c:1534
Again, the error mentions that the role is "reserved".
Also note the `rdsutils.c` mention. That's not a stock Postgres source file. This means that the logic comes
Also note the `rdsutils.c` mention. That's not a stock Postgres source file. This means that the logic comes
from an RDS extension. We can confirm this is the case by showing the preloaded libraries.
```sql
@@ -63,19 +63,19 @@ show shared_preload_libraries;
rdsutils,pg_stat_statements
```
`rdsutils` can be seen there. Naturally this lead us into thinking we can achieve the same logic with an extension
`rdsutils` can be seen there. Naturally this lead us into thinking we can achieve the same logic with an extension
of our own, and thus the SupaUtils idea was born.
## Extending PostgreSQL with Hooks
PostgreSQL hooks allow us to extend internal functionality. Hooks can modify behavior at different places,
PostgreSQL hooks allow us to extend internal functionality. Hooks can modify behavior at different places,
including when running SQL statements.
For example, if we wanted to enforce our own password restrictions whenever a user changes passwords, we could
use the `check_password_hook` to verify the password. We would write out our own Custom Logic, and raise an error
For example, if we wanted to enforce our own password restrictions whenever a user changes passwords, we could
use the `check_password_hook` to verify the password. We would write out our own Custom Logic, and raise an error
if the password fails the password requirements.
![This is an images of the lifecycle of a Postgres Hook.](/new/images/blog/postgres-hooks/hooks-postgres-alter-role.png)
![This is an images of the lifecycle of a Postgres Hook.](/images/blog/postgres-hooks/hooks-postgres-alter-role.png)
For `SupaUtils`, we're particularly interested in the `ProcessUtility_hook`, which allows us to hook into **utility statements:** every statement except `select`, `insert`, `delete` or `update`. They include `alter role` and `drop role`, which are the statements we want to hook on.
@@ -31,17 +31,17 @@ Watch a full demo of this month's releases
## Vercel integration
Vercel just released their new integrations, which means you can now deploy a Postgres database on Supabase directly from your Vercel account.
Vercel just released their new integrations, which means you can now deploy a Postgres database on Supabase directly from your Vercel account.
Check it out! [vercel.com/integrations/supabase](https://vercel.com/integrations/supabase)
![Supabase Vercel Integration](/new/images/blog/2021-june/supabase-vercel.png)
![Supabase Vercel Integration](/images/blog/2021-june/supabase-vercel.png)
## Discord logins are now available
Building a community? There's almost no better tool than Discord (we're even trialling it ourselves).
Building a community? There's almost no better tool than Discord (we're even trialling it ourselves).
If you're building a community product, Discord logins are the perfect option.
![Discord logins](/new/images/blog/2021-june/supabase-discord.png)
![Discord logins](/images/blog/2021-june/supabase-discord.png)
## New Guides
@@ -49,59 +49,59 @@ We spent the month building up a new [Guides section](https://supabase.io/docs/g
### Postgres Full Text Search
Ever wanted to build a Search Engine? We just released a guide which shows you how to implement
[Full Text Search using Postgres](https://supabase.io/docs/guides/database/full-text-search).
Ever wanted to build a Search Engine? We just released a guide which shows you how to implement
[Full Text Search using Postgres](https://supabase.io/docs/guides/database/full-text-search).
![Postgres Full Text Search](/new/images/blog/2021-june/postgres-fts.png)
![Postgres Full Text Search](/images/blog/2021-june/postgres-fts.png)
### OAuth Guides
We released step-by-step guides to help you set up OAuth with
[Apple](https://supabase.io/docs/guides/auth/auth-apple),
[Bitbucket](https://supabase.io/docs/guides/auth/auth-bitbucket),
[Facebook](https://supabase.io/docs/guides/auth/auth-facebook),
[GitHub](https://supabase.io/docs/guides/auth/auth-github),
[GitLab](https://supabase.io/docs/guides/auth/auth-gitlab),
[Google](https://supabase.io/docs/guides/auth/auth-google), and
[Twitter](https://supabase.io/docs/guides/auth/auth-twitter).
We released step-by-step guides to help you set up OAuth with
[Apple](https://supabase.io/docs/guides/auth/auth-apple),
[Bitbucket](https://supabase.io/docs/guides/auth/auth-bitbucket),
[Facebook](https://supabase.io/docs/guides/auth/auth-facebook),
[GitHub](https://supabase.io/docs/guides/auth/auth-github),
[GitLab](https://supabase.io/docs/guides/auth/auth-gitlab),
[Google](https://supabase.io/docs/guides/auth/auth-google), and
[Twitter](https://supabase.io/docs/guides/auth/auth-twitter).
![Image of Apple's developer Portal](/new/images/blog/2021-june/apple-developer-portal.png)
![Image of Apple's developer Portal](/images/blog/2021-june/apple-developer-portal.png)
### Javascript + Postgres
Did you know that you can use Javascript inside your Postgres database? Here's how, with the
Did you know that you can use Javascript inside your Postgres database? Here's how, with the
[`plv8` extension](https://supabase.io/docs/guides/database/extensions/plv8).
![Postgres and Javascript with plv8](/new/images/blog/2021-june/supabase-plv8.png)
![Postgres and Javascript with plv8](/images/blog/2021-june/supabase-plv8.png)
## Public Storage Buckets
Want to share all your favourite memes? Now it's even easier with Public Storage Buckets. Simply mark a bucket as
Want to share all your favourite memes? Now it's even easier with Public Storage Buckets. Simply mark a bucket as
"Public" and the content will be accessible without a login.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
<source src="/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
</video>
## Storage upserts
Supabase Storage now supports `upsert`. Shoutout to [@ankitjena](https://github.com/ankitjena) for
Supabase Storage now supports `upsert`. Shoutout to [@ankitjena](https://github.com/ankitjena) for
[this Pull Request](https://github.com/supabase/storage-api/pull/32).
![Storage now supports upserts](/new/images/blog/2021-june/supabase-storage-upsert.png)
![Storage now supports upserts](/images/blog/2021-june/supabase-storage-upsert.png)
## Server restarts
When things go wrong, sometime the best thing you can do is reboot. We released a restart button in the Dashboard,
When things go wrong, sometime the best thing you can do is reboot. We released a restart button in the Dashboard,
the first of many debugging tools we'll be releasing over the next few months.
![You can now restart you Supabase servers](/new/images/blog/2021-june/server-restarts.png)
![You can now restart you Supabase servers](/images/blog/2021-june/server-restarts.png)
## Policy editor
We added a new Table Policy Editor which makes Row Level Security even easier. We even included a few templates to get you started.
![New editor for Row Level Security](/new/images/blog/2021-june/policy-editor.png)
![New editor for Row Level Security](/images/blog/2021-june/policy-editor.png)
## Build in Public
@@ -122,22 +122,21 @@ We run a weekly 1-hour live stream where we build in public.
allowFullScreen
></iframe>
## Community
- [@dabit3](https://twitter.com/dabit3) released a complete guide to Supabase on FreeCodeCamp. [Twitter](https://twitter.com/freeCodeCamp/status/1404469119525732357) | [Blog](https://www.freecodecamp.org/news/the-complete-guide-to-full-stack-development-with-supabas/)
- [@raddevon](https://twitter.com/raddevon) built a social network using Supabase and Vue3. [Twitter](https://twitter.com/raddevon/status/1410401132845801479) | [YouTube](https://www.youtube.com/watch?v=x25a_q0vHUY)
- [@JonoYeong](https://twitter.com/JonoYeong) built live with Supabase + SvelteKit. [Twitter](https://twitter.com/JonoYeong/status/1409960155093946368) | [Twitch](https://www.twitch.tv/videos/1066520882)
**Supabase Github Star Growth** 
**Supabase Github Star Growth**
![14200 stars on GitHub.](/new/images/blog/2021-june/github-june-2021.png)
![14200 stars on GitHub.](/images/blog/2021-june/github-june-2021.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
</small>
If you want to keep up to date, make sure you [subscribe to our YouTube channel](https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ) or
If you want to keep up to date, make sure you [subscribe to our YouTube channel](https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ) or
[follow us on Twitter](https://twitter.com/supabase).
## External contributions
@@ -145,23 +144,23 @@ If you want to keep up to date, make sure you [subscribe to our YouTube channel]
### PostgREST
- Primarily for Prisma users, we patched PostgREST [openapi-mode](https://github.com/PostgREST/postgrest/pull/1881) to ignore anon privileges for the OpenAPI output.
Credit to [@steve-chavez](https://github.com/steve-chavez/).
Credit to [@steve-chavez](https://github.com/steve-chavez/).
- We added better [PostgREST logging](https://github.com/PostgREST/postgrest/pull/1872) to include timestamps for every error
Credit to [@steve-chavez](https://github.com/steve-chavez/).
Credit to [@steve-chavez](https://github.com/steve-chavez/).
### Auth0
- We fixed a XSS bug in the Auth0 Next.js library. [GitHub](https://github.com/auth0/nextjs-auth0/security/advisories/GHSA-954c-jjx6-cxv7)
Credit to [@inian](https://github.com/inian) and [Ishan Patel](https://github.com/git-ishanpatel) (a Supabase community member)
- We fixed a XSS bug in the Auth0 Next.js library. [GitHub](https://github.com/auth0/nextjs-auth0/security/advisories/GHSA-954c-jjx6-cxv7)
Credit to [@inian](https://github.com/inian) and [Ishan Patel](https://github.com/git-ishanpatel) (a Supabase community member)
## Coming Next
Launch Week!! Remember that time we did a [Launch Week](https://supabase.io/blog/2021/03/25/launch-week)? Well we're doing it again at the end of July.
Strap in, because we're shipping one thing every day for a week.
Launch Week!! Remember that time we did a [Launch Week](https://supabase.io/blog/2021/03/25/launch-week)? Well we're doing it again at the end of July.
Strap in, because we're shipping one thing every day for a week.
Let's goooooo.
![Launch week coming up.](/new/images/blog/supabase-launch-week.png)
![Launch week coming up.](/images/blog/supabase-launch-week.png)
### Get started
@@ -23,7 +23,7 @@ Just like last time, we don't want to spoil the surprise. So for now we'll give
## Monday 26 July: Community Day
![Supabase Community](/new/images/blog/launch-week-sql/community-day.png)
![Supabase Community](/images/blog/launch-week-sql/community-day.png)
### **When?**
@@ -39,7 +39,7 @@ Read the [blog post](/blog/2021/07/26/supabase-community-day).
## Tuesday 27 July: Storage v2
![Supabase storage v2](/new/images/blog/launch-week-sql/storage.png)
![Supabase storage v2](/images/blog/launch-week-sql/storage.png)
### **When?**
@@ -55,7 +55,7 @@ Read the [blog post](/blog/2021/07/27/storage-beta).
## Wednesday 28 July: Auth v2
![Supabase Auth v2](/new/images/blog/launch-week-sql/auth-v2.png)
![Supabase Auth v2](/images/blog/launch-week-sql/auth-v2.png)
### **When?**
@@ -71,7 +71,7 @@ Read the [blog post](/blog/2021/07/28/supabase-auth-passwordless-sms-login).
## Thursday 29 July: Dashboard v2
![Supabase Dashboards](/new/images/blog/launch-week-sql/dashboards.png)
![Supabase Dashboards](/images/blog/launch-week-sql/dashboards.png)
### **When?**
@@ -87,7 +87,7 @@ Read the [blog post](/blog/2021/07/29/supabase-reports-and-metrics).
## Friday 30 July: One more thing
![Supabase prequels](/new/images/blog/launch-week-sql/prequel.png)
![Supabase prequels](/images/blog/launch-week-sql/prequel.png)
### **When?**
@@ -101,8 +101,7 @@ We all know that the best [SeQueLs](https://www.reddit.com/r/SequelMemes/) are a
Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately.
[^1]:
When we first announced, Storage was on Wednesday and Auth was on Tuesday. We switched the order of these as we are doing a
Storage [presentation](https://www.meetup.com/the-monthly-dev-world-class-talks-by-expert-developers/events/278158726/) with
[daily.dev](https://daily.dev/) on Wednesday.
[^1]:
When we first announced, Storage was on Wednesday and Auth was on Tuesday. We switched the order of these as we are doing a
Storage [presentation](https://www.meetup.com/the-monthly-dev-world-class-talks-by-expert-developers/events/278158726/) with
[daily.dev](https://daily.dev/) on Wednesday.
+22 -22
View File
@@ -13,37 +13,37 @@ date: '2021-07-26'
toc_depth: 2
---
Epsilon3 is a USA-based Y Combinator startup. They digitize paper-based procedures in the space industry using telemetry data,
Epsilon3 is a USA-based Y Combinator startup. They digitize paper-based procedures in the space industry using telemetry data,
simplifying testing and operations. Their product is rapidly becoming the OS for space projects and complex operations.
Learn how the team at Epsilon3 uses Supabase to help teams execute secure and reliable operations in an industry where project
Learn how the team at Epsilon3 uses Supabase to help teams execute secure and reliable operations in an industry where project
spend runs into the billions.
### Space Operations
Epsilon3's customers run testing and operational procedures in real-time. Epsilon3's solution allows online collaboration as a team,
instead of being siloed and separated which is an increasingly important requirement in a post-pandemic working world.
Epsilon3's customers run testing and operational procedures in real-time. Epsilon3's solution allows online collaboration as a team,
instead of being siloed and separated which is an increasingly important requirement in a post-pandemic working world.
Epsilon3 is powering an industry where reliability is paramount. In the space industry, missions cost billions and need to run reliably.
![Epsilon3 digitizes paper-based processes.](/new/images/blog/epsilon3/epsilon3-product.gif)
![Epsilon3 digitizes paper-based processes.](/images/blog/epsilon3/epsilon3-product.gif)
Epsilon3's software saves operators time and reduces errors to improve complex operations. Their customers are using their software and
successfully sending satellites into space and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
reputation for improving the quality standard for complex operations has led to demand from other industries. The team is receiving
enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardized way of running
Epsilon3's software saves operators time and reduces errors to improve complex operations. Their customers are using their software and
successfully sending satellites into space and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
reputation for improving the quality standard for complex operations has led to demand from other industries. The team is receiving
enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardized way of running
procedures and keeping audit trails.
## Moving fast in regulated markets
As a startup, Epsilon3 needs to move fast and scale. They require security, reliability, and performance.
The team has a background in engineering from Northrop, Google, and SpaceX and understands the technical benefits Postgres offers as a
The team has a background in engineering from Northrop, Google, and SpaceX and understands the technical benefits Postgres offers as a
battle-tested open-source relational database.
Real-time functionality is also a key for their customers to see how running procedures are progressing as the changes occur.
The space industry is highly regulated, adding complexity. For example, in the USA, deployments must be in an ITAR-compliant way
(for instance AWS GovCloud supports ITAR compliance) while customers in countries outside the USA may need to host their data within their own
The space industry is highly regulated, adding complexity. For example, in the USA, deployments must be in an ITAR-compliant way
(for instance AWS GovCloud supports ITAR compliance) while customers in countries outside the USA may need to host their data within their own
country. These customer requirements mean Epsilon3 must be able to offer flexible hosting options, including on-premises deployment.
<Quote
@@ -68,22 +68,22 @@ country. These customer requirements mean Epsilon3 must be able to offer flexibl
### Supabase gives Postgres users Superpowers
The team implemented a self-hosted Supabase setup. They use AWS with a self-hosted Supabase API powering an RDS Postgres instance.
This setup gives a balance of rapid development, reduced DevOps, and flexible hosting options. As Supabase uniquely offers real-time for
Postgres, it allows their customers to see updates from running procedures. Supabase offers well-supported client libraries that make
The team implemented a self-hosted Supabase setup. They use AWS with a self-hosted Supabase API powering an RDS Postgres instance.
This setup gives a balance of rapid development, reduced DevOps, and flexible hosting options. As Supabase uniquely offers real-time for
Postgres, it allows their customers to see updates from running procedures. Supabase offers well-supported client libraries that make
Postgres Row Level Security easy to use, which is a critical item on the Epsilon3 roadmap.
All this was easy for the team to set up, even with self-hosting, so the team was able to focus on what they do best&mdash;helping their customers
run complex operations smoothly. With this implementation, Epsilon3 gets all the benefits of Postgres, plus the smooth developer experience and
All this was easy for the team to set up, even with self-hosting, so the team was able to focus on what they do best&mdash;helping their customers
run complex operations smoothly. With this implementation, Epsilon3 gets all the benefits of Postgres, plus the smooth developer experience and
support that Supabase is known for, without compromising their compliance needs.
![Epsilon3 uses Supabase for hosting their critical infrastructure.](/new/images/blog/epsilon3/supabase-epsilon3-architecture.png)
![Epsilon3 uses Supabase for hosting their critical infrastructure.](/images/blog/epsilon3/supabase-epsilon3-architecture.png)
### Self-hosted Supabase, a superpower
Self-hosting Supabase allows the crew at Epsilon3 to move fast. They are revolutionizing space operations securely and reliably in real-time whilst
staying compliant. The team is now seeing demand from other industries and is confident in their scaling capability because they know it's
just Postgres under the hood.
Self-hosting Supabase allows the crew at Epsilon3 to move fast. They are revolutionizing space operations securely and reliably in real-time whilst
staying compliant. The team is now seeing demand from other industries and is confident in their scaling capability because they know it's
just Postgres under the hood.
Check out the [Epsilon3 website](https://www.epsilon3.io/) to learn more about the team and their OS for space operations. If you are interested
Check out the [Epsilon3 website](https://www.epsilon3.io/) to learn more about the team and their OS for space operations. If you are interested
in self-hosting Supabase then you can **contact us** to learn more.
+22 -22
View File
@@ -13,26 +13,26 @@ date: '2021-07-26'
toc_depth: 2
---
Supabase has grown a lot [^1] since last [Launch Week](https://supabase.io/blog/2021/03/25/launch-week),
but it wouldn't be possible without some amazing open source tools.
Since we're shipping a few upgrades this week we feel it's only fair
to shine a spotlight on some tools and community efforts that make Supabase possible.
Supabase has grown a lot [^1] since last [Launch Week](https://supabase.io/blog/2021/03/25/launch-week),
but it wouldn't be possible without some amazing open source tools.
Since we're shipping a few upgrades this week we feel it's only fair
to shine a spotlight on some tools and community efforts that make Supabase possible.
## PostgreSQL version 13.3
![Postgres version 13 released](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgres-upgrade.jpg)
![Postgres version 13 released](/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgres-upgrade.jpg)
PostgreSQL is a big part of Supabase, and it's also a huge inspiration - the speed that they ship, their community organization,
and their absolute dedication towards reliability. PostgreSQL 13.3 was released in June and (from today) every new Supabase project will
PostgreSQL is a big part of Supabase, and it's also a huge inspiration - the speed that they ship, their community organization,
and their absolute dedication towards reliability. PostgreSQL 13.3 was released in June and (from today) every new Supabase project will
be on [PostgreSQL version 13.3](/blog/2021/07/26/supabase-postgres-13).
### Giving back
Supabase makes it easy to get started with Postgres, but we think you should try it even if you don't want to use Supabase. Here's a
Supabase makes it easy to get started with Postgres, but we think you should try it even if you don't want to use Supabase. Here's a
few ways we make it easy to use PostgreSQL without Supabase:
- Supabase was the first company to put Postgres in the [Digital Ocean Marketplace](https://marketplace.digitalocean.com/apps/supabase-postgres).
Since then it's been installed over 1000 times (not by us!).
- Supabase was the first company to put Postgres in the [Digital Ocean Marketplace](https://marketplace.digitalocean.com/apps/supabase-postgres).
Since then it's been installed over 1000 times (not by us!).
- We provide a Postgres image in the [AWS marketplace](https://aws.amazon.com/marketplace/pp/prodview-lk2pfa5nafecg).
- We're packaging the Marketplace version, [along with "Bundles"](/blog/2021/07/26/supabase-postgres-13#postgresql-bundles)
- We're developing a few extensions: [supautils](https://github.com/supabase/supautils), [pg_net](https://github.com/supabase/pg_net), and a couple more soon to be announced.
@@ -44,32 +44,32 @@ Since then it's been installed over 1000 times (not by us!).
## PostgREST version 8.0
![PostgREST version 8.0 released](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgrest.jpg)
![PostgREST version 8.0 released](/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-postgrest.jpg)
This new PostgREST stable version comes with the improvements we've made to make it truly enterprise-grade. Due to our commitment with OSS,
all of our improvements are upstreamed, so you can fully use them on your own self-hosted projects.
### Highlights
**Improved Performance**: Due to Supabase's high throughput requirements, PostgREST 8.0 handles up to 50% more throughput on
GET requests, according to our benchmarks. We converted all SELECT queries to use prepared statements and reduced logging
**Improved Performance**: Due to Supabase's high throughput requirements, PostgREST 8.0 handles up to 50% more throughput on
GET requests, according to our benchmarks. We converted all SELECT queries to use prepared statements and reduced logging
verbosity to make this possible.
**Reduced downtime**: we need PostgREST to be more "set it and forget it", so reloading schema cache now has zero downtime.
**Dynamic Configuration**: we've made it easier to handle PostgREST configuration at scale (we manage thousands of PostgREST instances).
**Dynamic Configuration**: we've made it easier to handle PostgREST configuration at scale (we manage thousands of PostgREST instances).
This new version includes the ability to use an in-database configuration that is reloadable through a `NOTIFY` command.
**Less admin burden**: PostgREST previously required the `pg_listen` utility to reload its schema cache. This is no longer needed.
**Less admin burden**: PostgREST previously required the `pg_listen` utility to reload its schema cache. This is no longer needed.
The schema cache is reloadable with a simple `NOTIFY` command.
**Better diagnostic information**: in the rare cases where PostgREST fails, we want to find the exact root cause quickly.
**Better diagnostic information**: in the rare cases where PostgREST fails, we want to find the exact root cause quickly.
For this we've improved its logging by adding logging levels and timestamps to all server errors.
**Simpler OpenAPI**: showing a complete OpenAPI output used to require a highly-privileged `anon` role. With the new `openapi-mode`,
this is no longer needed and `anon` can be kept with minimal privileges.
The community has made many more enhancements and bug fixes for the new version. See
The community has made many more enhancements and bug fixes for the new version. See
[v8.0 CHANGELOG](https://github.com/PostgREST/postgrest/releases/tag/v8.0.0) for the full list.
### Get Started
@@ -94,7 +94,7 @@ Want to get started with PostgREST? The Supabase community has built a number of
## Supabase Flutter/Dart (Beta release)
![Supabase Flutter Beta release](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-flutter-library.jpg)
![Supabase Flutter Beta release](/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-flutter-library.jpg)
While the Supabase team have been busy with the Javascript libraries, the community have been beavering away with Dart. They've even
[built fully-functional apps](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc) using Supabase Auth and Storage.
@@ -116,11 +116,11 @@ Today the Community are releasing both the Flutter and Dart libraries in Beta (w
## Supabase Discord
![Supabase Discord](/new/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-discord-server.jpg)
![Supabase Discord](/images/blog/launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-discord-server.jpg)
OK, OK, we get it - GitHub [Discussions](https://github.com/supabase/supabase/discussions) aren't enough for y'all. While we've been trying
to keep the conversation contained to our GitHub org, the community has been creating [subreddits](https://www.reddit.com/r/Supabase/),
StackOverflow [tags](https://stackoverflow.com/questions/tagged/supabase), and GitHub [topics](https://github.com/topics/supabase).
OK, OK, we get it - GitHub [Discussions](https://github.com/supabase/supabase/discussions) aren't enough for y'all. While we've been trying
to keep the conversation contained to our GitHub org, the community has been creating [subreddits](https://www.reddit.com/r/Supabase/),
StackOverflow [tags](https://stackoverflow.com/questions/tagged/supabase), and GitHub [topics](https://github.com/topics/supabase).
A few weeks ago one of the community created a Community-led Discord, and so the team figured we might as well join the fun.
@@ -63,7 +63,7 @@ Running the benchmark with 2, 4, 8, 16, 64, and 128 clients:
pgbench -P 5 -c {num_clients} -j {num_clients} -T 300 -M prepared postgres
```
![PostgreSQL 13.3 performance](/new/images/blog/pg13/postgres-13-performance.png)
![PostgreSQL 13.3 performance](/images/blog/pg13/postgres-13-performance.png)
## Ubuntu 20.04
@@ -98,7 +98,7 @@ ports `5432` (PostgreSQL) and `6543` (PgBouncer).
IPs get banned for 10 minutes after three failed attempts, and we'll continue to fine-tune and improve the protections applied to the
database servers based on evolving traffic patterns.
## PostgreSQL bundles
## PostgreSQL bundles
`[Coming Soon]`
@@ -15,65 +15,62 @@ toc_depth: 2
Learn why Tyler decided Flutter and Supabase are the perfect tech-stack shipping innovative ideas fast.
[Tyler Shukert](https://twitter.com/dshukertjr) is an indie developer who has been building websites and applications for seven years.
Tyler is a Firebase & Flutter expert who recently discovered Supabase. After falling in love with Supabase,
Tyler decided to launch his latest app. [Spot](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc)
[Tyler Shukert](https://twitter.com/dshukertjr) is an indie developer who has been building websites and applications for seven years.
Tyler is a Firebase & Flutter expert who recently discovered Supabase. After falling in love with Supabase,
Tyler decided to launch his latest app. [Spot](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc)
is a geolocation-based video-sharing app with some social networking features.
## NoSQL doesn't mean No Schema
Tyler loves how easy it is to create high-quality web and mobile applications with Firebase. For the past few years he has honed
his Flutter, Angular, and Firebase skills to quickly ship mobile and web apps. But the more his development expertise grew,
Tyler loves how easy it is to create high-quality web and mobile applications with Firebase. For the past few years he has honed
his Flutter, Angular, and Firebase skills to quickly ship mobile and web apps. But the more his development expertise grew,
the more he understood the limitations of Firebase.
Before starting a project, Tyler is never sure if the project will grow. It could be an overnight success, or it might need to
pivot in a different direction. He finds this is particularly difficult with Firebase as he faces a denormalization dilemma.
Denormalization means combining the data into a single table to make data retrieval faster. Google promotes denormalization
as best practice for a snappier app experience. Denormalisation in Firebase takes work and requires additional development
time. For new projects, it is often unclear if they will reach a scale justifying the effort denormalization requires.
Before starting a project, Tyler is never sure if the project will grow. It could be an overnight success, or it might need to
pivot in a different direction. He finds this is particularly difficult with Firebase as he faces a denormalization dilemma.
Denormalization means combining the data into a single table to make data retrieval faster. Google promotes denormalization
as best practice for a snappier app experience. Denormalisation in Firebase takes work and requires additional development
time. For new projects, it is often unclear if they will reach a scale justifying the effort denormalization requires.
In relational databases like Postgres, data is normalized, meaning reduced data redundancy with maintained data integrity.
## Supabase + Flutter: a match made in heaven
When Tyler discovered Supabase on Twitter, he was intrigued by the promise of Postgres with Firebase-like features.
When Tyler discovered Supabase on Twitter, he was intrigued by the promise of Postgres with Firebase-like features.
He wanted the benefits of SQL and Relational schemas, and decided to build an app to test Supabase.
Tyler had been thinking about building Spot, a mobile app for sharing geo-based video content. When he previously planned Spot,
he felt like hacking around Firebase would be too much effort. After researching the PostGIS extension for geospatial data,
he realized Supabase was the perfect fit. As an avid Flutter fan, Supabase's Dart library was a bonus.
Tyler had been thinking about building Spot, a mobile app for sharing geo-based video content. When he previously planned Spot,
he felt like hacking around Firebase would be too much effort. After researching the PostGIS extension for geospatial data,
he realized Supabase was the perfect fit. As an avid Flutter fan, Supabase's Dart library was a bonus.
Tyler loves the open-source nature of Supabase and immediately began contributing to the Dart library to enable functionality that he needed.
Tyler decided that Spot would be perfect to showcase the power of Supabase and Flutter. Since he's active in the open-source community,
Tyler decided that Spot would be perfect to showcase the power of Supabase and Flutter. Since he's active in the open-source community,
he decided to open-source the whole project, making Spot one of the most interesting Supabase examples.
![Spot screenshots.](/new/images/blog/spot/spot-screenshots.jpg)
![Spot screenshots.](/images/blog/spot/spot-screenshots.jpg)
## Comparing Firebase to Supabase
Although Spot seems simple, it has a lot of complicated components. Implementing social "Likes" requires `count` functionality,
which is notoriously tricky in Firebase. In Supabase, because it's just Postgres under the hood, `count` is implemented
Although Spot seems simple, it has a lot of complicated components. Implementing social "Likes" requires `count` functionality,
which is notoriously tricky in Firebase. In Supabase, because it's just Postgres under the hood, `count` is implemented
using a simple SQL `count` query.
Supabase has Row-Level Security, which Tyler uses as a filter - something he can't do with Firebase.
Spot uses Supabase Storage for managing large video files. Firebase Storage [has a reputation](https://stackoverflow.com/questions/43851742/firebase-storage-very-slow-compared-to-firebase-hosting) for slowness until it is public, which was a privacy concern for Tyler. With Supabase Storage, this wasn't an issue - storage is performant and secure.
The Firebase API pricing model makes it is difficult to predict pricing upfront for new projects. With Supabase,
The Firebase API pricing model makes it is difficult to predict pricing upfront for new projects. With Supabase,
Tyler doesn't need to worry about how many API calls his project makes.
Supabase gives Spot speed, performance, and predictable pricing.
As of today, Tyler has around 3000 installs for Spot and is getting ready to add new functionality. He is confident Supabase,
As of today, Tyler has around 3000 installs for Spot and is getting ready to add new functionality. He is confident Supabase,
Postgres, and his data structure will enable future development.
<Quote
img="tyler-spot.jpg"
caption="Tyler Shukert, creator of Spot."
>
<Quote img="tyler-spot.jpg" caption="Tyler Shukert, creator of Spot.">
<p>
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build apps faster than ever.
For apps like Spot where we handle user submitted files, it is very easy to manage them securely.
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build
apps faster than ever. For apps like Spot where we handle user submitted files, it is very easy
to manage them securely.
</p>
<p>
Supabaseを最初発見した時にこれとFlutterを組み合わせれば今まで以上に爆速でアプリ開発ができるだろうと思いました。
@@ -81,14 +78,13 @@ Postgres, and his data structure will enable future development.
</p>
</Quote>
## Spot is Open Source
With Supabase, Tyler can use Flutter to build a performant app quickly at a low cost. Tyler is now a massive fan of the Supabase
experience and has even joined the SupaSquad.
With Supabase, Tyler can use Flutter to build a performant app quickly at a low cost. Tyler is now a massive fan of the Supabase
experience and has even joined the SupaSquad.
You can download and install spot for [iOS](https://apps.apple.com/us/app/spot-videos/id1564675926?utm_source=supabase&utm_campaign=static)
and [Android](https://play.google.com/store/apps/details?id=app.spotvideo&utm_source=supabase&utm_campaign=static)
to see just how snappy his setup is.
Tyler has fully open-sourced his example - you can [clone the repo](https://github.com/dshukertjr/spot)
You can download and install spot for [iOS](https://apps.apple.com/us/app/spot-videos/id1564675926?utm_source=supabase&utm_campaign=static)
and [Android](https://play.google.com/store/apps/details?id=app.spotvideo&utm_source=supabase&utm_campaign=static)
to see just how snappy his setup is.
Tyler has fully open-sourced his example - you can [clone the repo](https://github.com/dshukertjr/spot)
and use it as the basis of your next big idea.
+11 -11
View File
@@ -21,7 +21,7 @@ Clients can use the `Content-Range` HTTP header to request specific parts of a f
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/nyan-cat.mp4"
src="/videos/blog/launch-week-storage-2/nyan-cat.mp4"
type="video/mp4"
muted
playsInline
@@ -41,7 +41,7 @@ Objects in public buckets can be accessed via a URL without any Authorization to
Public buckets still require [Auth Policies](https://supabase.io/docs/guides/storage#policy-examples) to upload and delete objects, allowing you to securely manage their contents.
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source src="/new/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
<source src="/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
</video>
## Directory uploads
@@ -50,7 +50,7 @@ You can now upload an entire directory to Supabase Storage and the directory str
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/directory-uploads.mp4"
src="/videos/blog/launch-week-storage-2/directory-uploads.mp4"
type="video/mp4"
muted
playsInline
@@ -63,11 +63,11 @@ Postgres [Row Level Security](https://www.postgresql.org/docs/13/ddl-rowsecurity
However, getting started with RLS can be daunting. To make it more approachable for beginners, we've included a set of pre-defined templates on our Dashboard, covering common use-cases.
![Policy editor templates](/new/images/blog/launch-week-sql-day-2/policy-editor-1.png)
![Policy editor templates](/images/blog/launch-week-sql-day-2/policy-editor-1.png)
Once you've selected a template, you choose which operations to allow and the Dashboard determines which API functions can access the bucket. For example, a user with INSERT permissions will be able to call the `createObject`, `copyObject` and `getSignedObject` functions in the `supabase-js` library.
![Policy editor permissions](/new/images/blog/launch-week-sql-day-2/policy-editor-2.png)
![Policy editor permissions](/images/blog/launch-week-sql-day-2/policy-editor-2.png)
After writing the policy definition (which can be any valid SQL expression), you get an opportunity to review the final policy before saving. We made sure that there is no magic going on behind the scenes: you can always see the underlying SQL definition of the policies. As you become more comfortable with Row Level Security, you can define these policies directly using our SQL editor.
@@ -87,13 +87,13 @@ However, `FormData` is only supported in the browser, making `supabase-js` incom
At Supabase, we are [maniacal about performance](https://supabase.io/blog/2020/12/13/supabase-dashboard-performance). Keeping our client libraries lean is a key differentiator. Our entire client library (including the clients for postgrest, storage, realtime and auth) is just 15.8 kb. If you are just interested in using a single service like storage, you can use the `storage-js` library directly which is [even smaller](https://bundlephobia.com/package/@supabase/storage-js@1.4.0). This made including polyfills like Formdata a no-go.
![Supabase JS bundle size](/new/images/blog/launch-week-sql-day-2/supabase-js-size.png)
![Supabase JS bundle size](/images/blog/launch-week-sql-day-2/supabase-js-size.png)
We also considered shipping separate bundles for Node.js and the browser. This would have avoided polyfills for APIs which are already supported in each browser. However, this comes with an increase in complexity to our build process, and users would need to choose which flavor of the library to use in different environments like React Native, Deno, etc. We want to make our libraries universal.
Instead, we modified the storage server to accept Binary data directly. With this change, you can directly upload binary Data and even NodeJS streams to the storage API.
![NodeJS Stream upload](/new/images/blog/launch-week-sql-day-2/stream-upload.png)
![NodeJS Stream upload](/images/blog/launch-week-sql-day-2/stream-upload.png)
With this change in place, the client library supports uploading `ArrayBuffer`, `ArrayBufferView`, `Blob`, `Buffer`, `File`, `FormData`, `NodeJS.ReadableStream`, `ReadableStream<Uint8Array>` - without any change to the bundle size! This should enable you to use storage from an even wider range of environments.
@@ -102,10 +102,10 @@ With this change in place, the client library supports uploading `ArrayBuffer`,
The storage explorer in our Dashboard feels like using a file explorer in your operating system. There were a lot of challenges to make it feel intuitive and robust, since S3 is not a traditional filesystem. For example, S3 doesn't support a move operation natively - you need to copy the object to the new location and delete the original object. S3 also doesn't have a concept of directory, which means there is no API call to rename a directory. But to make the storage explorer feel like a native file explorer, we implemented these features.
Context menus on folders
![Context menu 1](/new/images/blog/launch-week-sql-day-2/context-menu-1.png)
![Context menu 1](/images/blog/launch-week-sql-day-2/context-menu-1.png)
Context menus on files
![Context menu 2](/new/images/blog/launch-week-sql-day-2/context-menu-2.png)
![Context menu 2](/images/blog/launch-week-sql-day-2/context-menu-2.png)
### The case of the disappearing folders
@@ -121,7 +121,7 @@ Here is a demo testing rendering the heaviest object known to mankind - the `nod
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
<source
src="/new/videos/blog/launch-week-storage-2/large-buckets.mp4"
src="/videos/blog/launch-week-storage-2/large-buckets.mp4"
type="video/mp4"
muted
playsInline
@@ -133,7 +133,7 @@ Here is a demo testing rendering the heaviest object known to mankind - the `nod
Supabase Storage now supports `upsert`. Shoutout to [@ankitjena](https://github.com/ankitjena) for
[this Pull Request](https://github.com/supabase/storage-api/pull/32).
![Storage now supports upserts](/new/images/blog/2021-june/supabase-storage-upsert.png)
![Storage now supports upserts](/images/blog/2021-june/supabase-storage-upsert.png)
We also have automated API docs generated [here](https://supabase.github.io/storage-api/#/) if you want to use the Storage API directly.
@@ -14,80 +14,76 @@ date: '2021-07-28'
toc_depth: 2
---
Learn how Mobbin migrated 200,000 users from Firebase for a better authentication experience.
Mobbin helps over 200,000 creators globally search and view the latest design patterns from well-known apps.
Their platform allows creators to search screenshots of mobile apps to inspire product development.
Mobbin helps over 200,000 creators globally search and view the latest design patterns from well-known apps.
Their platform allows creators to search screenshots of mobile apps to inspire product development.
Creators use Mobbin to combine inspiration and develop new experiences.
## From Idea to 30,000 users in one Product Hunt launch
The initial concept for Mobbin was just a Dropbox full of screenshots. After sharing with their early users,
the team tried organizing them into folders but this quickly became unscalable. Clear interest from users encouraged them to build a full website. They used Firebase for the backend and launched on
The initial concept for Mobbin was just a Dropbox full of screenshots. After sharing with their early users,
the team tried organizing them into folders but this quickly became unscalable. Clear interest from users encouraged them to build a full website. They used Firebase for the backend and launched on
[Product Hunt](https://www.producthunt.com/posts/mobbin-1).
Mobbin went viral, and within the first week they had 30,000 users. In just over two years, they have grown to over 200,000
registered users through word of mouth. Their curation continues to attract designers and creators globally.
Mobbin went viral, and within the first week they had 30,000 users. In just over two years, they have grown to over 200,000
registered users through word of mouth. Their curation continues to attract designers and creators globally.
![Mobbin cover](/new/images/blog/mobbin/mobbin-cover.png)
![Mobbin cover](/images/blog/mobbin/mobbin-cover.png)
## Scaling issues put Mobbin growth at risk
Firebase helped the team launch quickly, but at scale, they found Firebase lacked the functionality required for a high-quality user experience.
The first problem was duplicate user logins. Firebase Authentication doesn't automatically merge users with the same email address.
For example, users cannot log in with Google and Facebook if they share the same email address.
The first problem was duplicate user logins. Firebase Authentication doesn't automatically merge users with the same email address.
For example, users cannot log in with Google and Facebook if they share the same email address.
Users struggled to upgrade to a paid account because they couldn't remember which authentication provider they signed up with.
Next, they had issues with data integrity. While Firebase has 99.95% uptime, application code can (and does) fail.
Mobbin didn't want to implement idempotence for every mutative Firebase Function. Between a failed Function execution and a retry,
Next, they had issues with data integrity. While Firebase has 99.95% uptime, application code can (and does) fail.
Mobbin didn't want to implement idempotence for every mutative Firebase Function. Between a failed Function execution and a retry,
a document state might change without strict validation. The team could never be confident their data had the level of integrity they required.
Finally, the team grew concerned with their increasing Firebase bill. Because of the document-based data structure,
their API requests required several round trips. At one point, they were making 5 million API requests per month.
Finally, the team grew concerned with their increasing Firebase bill. Because of the document-based data structure,
their API requests required several round trips. At one point, they were making 5 million API requests per month.
These round trips made their website slow and led to a notable time investment hacking together a fix.
![Mobbing screenshots](/new/images/blog/mobbin/mobbin-screenshots.jpg)
![Mobbing screenshots](/images/blog/mobbin/mobbin-screenshots.jpg)
## Migrating to Supabase
Mobbin's initial product gave them a comprehensive understanding of customer requirements. For their second version,
they needed a better authentication experience, fairer pricing, and a relational database to deliver a quality
Mobbin's initial product gave them a comprehensive understanding of customer requirements. For their second version,
they needed a better authentication experience, fairer pricing, and a relational database to deliver a quality
application sustainable for their business model.
The team found Supabase and realized it covered all the bases. Not only that, their team had experience with the
The team found Supabase and realized it covered all the bases. Not only that, their team had experience with the
tools open source tools that Supabase is built with.
Auth, built using [GoTrue](https://github.com/supabase/gotrue), instantly solved their users' login issues.
Under the hood, Supabase is just Postgres, and Jian Jie (co-founder and CTO of Mobbin) knows this is one of the best battle-tested
Auth, built using [GoTrue](https://github.com/supabase/gotrue), instantly solved their users' login issues.
Under the hood, Supabase is just Postgres, and Jian Jie (co-founder and CTO of Mobbin) knows this is one of the best battle-tested
open source relational databases.
They decided that moving to Supabase was a no-brainer. The process itself was smooth - the real challenge was validating their
They decided that moving to Supabase was a no-brainer. The process itself was smooth - the real challenge was validating their
data integrity due to historical failures on their serverless functions.
Mobbin is now successfully running on top of Supabase, with superior performance compared to their old Firebase setup.
Mobbin is now successfully running on top of Supabase, with superior performance compared to their old Firebase setup.
Because Supabase does not charge based on API requests, Mobbin significantly reduced their monthly spending without maintaining a custom backend.
<Quote
img="jian-mobbin.jpg"
caption="Jian Jie Liau, Co-founder and CTO at Mobbin."
>
<Quote img="jian-mobbin.jpg" caption="Jian Jie Liau, Co-founder and CTO at Mobbin.">
<p>Migrating to Supabase meant that we could instantly fix our Auth problems and save money.</p>
<p>
Just being on Supabase alone gives us confidence we can deliver on whatever users need in the future.
Just being on Supabase alone gives us confidence we can deliver on whatever users need in the
future.
</p>
<p>
The cool thing is now we know under the hood it's just Postgres, it really does feel like anything is possible for the future of our product
The cool thing is now we know under the hood it's just Postgres, it really does feel like
anything is possible for the future of our product
</p>
</Quote>
## Supabase saves Mobbin time and money
Migrating to Supabase helped the team at Mobbin instantly improve the end-user experience and save costs.
They now add new features with confidence, and they continue to help creators all over the globe find inspiration for their next project.
Migrating to Supabase helped the team at Mobbin instantly improve the end-user experience and save costs.
They now add new features with confidence, and they continue to help creators all over the globe find inspiration for their next project.
You can [check out Mobbin on their website](https://mobbin.design/browse/ios/apps).
Sign up to Supabase's free tier and set up a scalable backend in less than 2 minutes.
@@ -14,46 +14,44 @@ date: '2021-07-28'
toc_depth: 3
---
Since launching Supabase Auth [last summer](https://news.ycombinator.com/item?id=24072051) it's proven to be a key part of the Supabase Stack.
We receive a constant stream of feature requests and community PRs resulting in a long
Since launching Supabase Auth [last summer](https://news.ycombinator.com/item?id=24072051) it's proven to be a key part of the Supabase Stack.
We receive a constant stream of feature requests and community PRs resulting in a long
list of external providers including GitHub, Discord, Azure, Apple and more.
Supabase Auth is similar to Auth0 and Firebase Auth with one major difference - the user data lives in your own database,
reducing lock-in, and making the auth system more extensible. You can write native PostgreSQL Row Level Security policies to
determine which data your users should (or should not) have access to. It can even be used in conjunction with other Supabase features,
Supabase Auth is similar to Auth0 and Firebase Auth with one major difference - the user data lives in your own database,
reducing lock-in, and making the auth system more extensible. You can write native PostgreSQL Row Level Security policies to
determine which data your users should (or should not) have access to. It can even be used in conjunction with other Supabase features,
such as [Storage](https://supabase.io/storage), to control access for specific files and buckets.
Today we're announcing some major new features for our [fork](https://github.com/supabase/gotrue) of Netlify's [GoTrue](https://github.com/netlify/gotrue) Auth server.
## Phone Auth is here!
Your users can now log in using their mobile with SMS-based OTPs (one-time password).
Your users can now log in using their mobile with SMS-based OTPs (one-time password).
### Passwordless SMS login
Users can log in using a passwordless SMS based OTP with `supabase-js`, or directly with the Auth API.
Users can log in using a passwordless SMS based OTP with `supabase-js`, or directly with the Auth API.
![Passwordless SMS login](/new/images/blog/auth-v2/passwordless-login.png)
![Passwordless SMS login](/images/blog/auth-v2/passwordless-login.png)
After logging in, the user will receive a six-digit One Time Password. The OTP can be easily verified.
![Use SMS and password to login](/new/images/blog/auth-v2/verify-otp.png)
![Use SMS and password to login](/images/blog/auth-v2/verify-otp.png)
### SMS login with passwords
Phone Auth can be used in conjunction with a password. Using this flow, your users can subsequently log in
Phone Auth can be used in conjunction with a password. Using this flow, your users can subsequently log in
with either an OTP or a phone + password combo.
![SMS login with passwords](/new/images/blog/auth-v2/phone-and-password-login.png)
![SMS login with passwords](/images/blog/auth-v2/phone-and-password-login.png)
### Choose an SMS Provider
Supabase Auth supports [Twilio](https://www.twilio.com/) as an SMS provider, with more options coming soon.
Simply plug your Twilio credentials into your Auth Settings in the Supabase Dashboard to get started.
Supabase Auth supports [Twilio](https://www.twilio.com/) as an SMS provider, with more options coming soon.
Simply plug your Twilio credentials into your Auth Settings in the Supabase Dashboard to get started.
Check out the [documentation](https://supabase.io/docs/guides/auth/auth-twilio) to get started with Mobile OTPs,
Check out the [documentation](https://supabase.io/docs/guides/auth/auth-twilio) to get started with Mobile OTPs,
or watch the [Youtube guide](https://youtu.be/akScoPO01bc).
<iframe
@@ -66,43 +64,42 @@ or watch the [Youtube guide](https://youtu.be/akScoPO01bc).
allowFullScreen
></iframe>
### Multi-Factor Auth coming soon
Phone Auth is available today on all new and existing Supabase projects. We've also laid the groundwork for mobile Multi-Factor
Phone Auth is available today on all new and existing Supabase projects. We've also laid the groundwork for mobile Multi-Factor
Auth and will be offering that as an option soon.
## Even more OAuth providers
The community has contributed tons of OAuth providers, and today we're announcing two more.
Shoutout to [@ph1p](https://github.com/ph1p) who contributed [Twitch](https://supabase.io/docs/guides/auth/auth-twitch) as our latest OAuth provider!
Shoutout to [@ph1p](https://github.com/ph1p) who contributed [Twitch](https://supabase.io/docs/guides/auth/auth-twitch) as our latest OAuth provider!
The Supabase team added [Discord](https://supabase.io/docs/guides/auth/auth-discord) last month, bringing the total OAuth Providers to ten.
![All Supabase OAuth providers](/new/images/blog/auth-v2/supabase-oauth-providers.png)
![All Supabase OAuth providers](/images/blog/auth-v2/supabase-oauth-providers.png)
You can request more providers on our [Auth repo](https://github.com/supabase/gotrue) and Pull Requests are, of course, always welcome.
## Generate Confirmation Links
To make life easy for developers, the Supabase hosted platform manages all Auth-related emails, including confirmation,
To make life easy for developers, the Supabase hosted platform manages all Auth-related emails, including confirmation,
recovery, invite, and passwordless "magic-link" emails. The templates are customizable and we even offer the ability to bring your own SMTP provider.
Some of our power users require a little more flexibility however. We've had a lot of requests to dynamically generate email content,
especially for sending internationalized emails. To handle situations like these, today we're adding the ability to
Some of our power users require a little more flexibility however. We've had a lot of requests to dynamically generate email content,
especially for sending internationalized emails. To handle situations like these, today we're adding the ability to
generate confirmation, invite, recovery, and magic links via an API endpoint.
We've exposed this functionality in `supabase-js`, and it can be invoked with the use of your `service_role` admin key
We've exposed this functionality in `supabase-js`, and it can be invoked with the use of your `service_role` admin key
(which means you should only be calling this function from a backend and not from the client itself).
![Generate Confirmation Links](/new/images/blog/auth-v2/generate-links.png)
![Generate Confirmation Links](/images/blog/auth-v2/generate-links.png)
## What's next?
The next major item on the list is MFA (Multi-Factor Authentication) - which includes TOTP
The next major item on the list is MFA (Multi-Factor Authentication) - which includes TOTP
([Time-Based One Time Password](https://en.wikipedia.org/wiki/Time-based_One-Time_Password)).
Find out how Mobbin is using Supabase Auth to [manage 200,000 users](/blog/2021/07/28/mobbin-supabase-200000-users).
Anything else you want to see or can help implement in Auth? Reach out on
Anything else you want to see or can help implement in Auth? Reach out on
[Discord](https://discord.supabase.com/) and give Auth a try by [creating a project](https://app.supabase.io/) on Supabase!
@@ -25,7 +25,7 @@ API requests across all of Supabase's core pillars:
Database, Auth and Storage. We've included two instance health metrics, CPU usage and Memory usage,
with a lot more on the way.
![Supabase reports screen](/new/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-reports-screen.jpg)
![Supabase reports screen](/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-reports-screen.jpg)
All charts are built with [Recharts](https://recharts.org/en-US), an MIT-licensed React chart library chosen for its ease of use.
We'll add customizable charts in the future, so we'd love to hear which libraries you'd like to see in Supabase.
@@ -42,7 +42,7 @@ number of Auth users, and Storage space.
And we're just getting warmed up. Over the next few months you'll see more project information, notifications, and highlights to
monitor your project health at a glance.
![Supabase new dashboard app homescreen](/new/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-homepage.jpg)
![Supabase new dashboard app homescreen](/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-homepage.jpg)
## Observability metrics
@@ -52,7 +52,7 @@ important infrastructure anomalies.
All databases are now launched with `pg_stat_statements` enabled, so you can expect some useful query statistics in the future too.
![Supabase observability metrics](/new/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-observability-screen.jpg)
![Supabase observability metrics](/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-and-metrics-observability-screen.jpg)
## Building a metrics pipeline
@@ -67,7 +67,7 @@ and to get ahead of possible issues before they become showstoppers.
At Supabase, each project is provisioned with a Postgres cluster, and a suite of associated services that add, ahem,
supa-powers to the database.
![Supabase architecture](/new/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-infra.png)
![Supabase architecture](/images/blog/launch-week-sql-day-4-reports-and-metrics/reports-infra.png)
Our users get liberal access to each of these services - you can use PostgREST for a RESTful API,
Realtime to listen to changes in your Postgres instance, or even just open a raw connection to the database.
@@ -98,7 +98,7 @@ We run [Prometheus](https://prometheus.io/) out of inertia, soon to be [Victoria
The monitoring instances scrape data from a number of exporters that are bundled into each of our projects.
A small subset of the metrics collected gets aggregated to a centralized VictoriaMetrics instance for easier cohort analysis.
![Supabase Prometheus](/new/images/blog/launch-week-sql-day-4-reports-and-metrics/prometheus.png)
![Supabase Prometheus](/images/blog/launch-week-sql-day-4-reports-and-metrics/prometheus.png)
### Available sources and metrics
@@ -28,7 +28,7 @@ The first Supabase Hackathon starts **right now**.
- Submission deadline is 11:59pm Friday night PDT (6th August 2021)
- You can win one of these extremely [Limited Edition Olympic Gold](https://store.supabase.com/products/hackathon-prize) and Silver Supabase T-Shirts
![Gold Tshirt](/new/images/blog/hackathon/tshirt.png)
![Gold Tshirt](/images/blog/hackathon/tshirt.png)
## Details
@@ -52,7 +52,7 @@ There are 5 chances to win, there will be prizes for:
There will be a winner and a runner-up prize for each category.
![Gold Tshirt](/new/images/blog/hackathon/prizes.png)
![Gold Tshirt](/images/blog/hackathon/prizes.png)
### Submission
@@ -64,10 +64,10 @@ You will be asked to send a link to a GitHub (or similar) repo, in the README yo
- list of team members GitHub handles (and Twitter if they have one)
- any demo videos, instructions, or memes
- a brief description of how you used Supabase:
- to store data?
- realtime?
- auth?
- storage?
- to store data?
- realtime?
- auth?
- storage?
- any other info you want the judges to know (motivations/ideas/process)
- optional team photo
@@ -80,7 +80,7 @@ We have assembled an All Star Judging Panel:
- The Supabase Team
- One more Mystery Guest
![Judges](/new/images/blog/hackathon/judges.png)
![Judges](/images/blog/hackathon/judges.png)
They will be looking for a few things, including:
@@ -89,8 +89,8 @@ They will be looking for a few things, including:
- visually pleasing
- technically impressive
- use of Supabase features
- deep usage of a single feature or
- broad usage are both ok
- deep usage of a single feature or
- broad usage are both ok
- FUN! 😃
### Rules
@@ -116,7 +116,7 @@ If you need help or advice when building, find other people to join your team, o
[Join our Discord](https://discord.supabase.com)
![Discord Hangout](/new/images/blog/hackathon/community.png)
![Discord Hangout](/images/blog/hackathon/community.png)
### Guides
@@ -14,31 +14,27 @@ date: '2021-07-30'
toc_depth: 3
---
The question on everyone's mind - are we launching Supabase Functions? Well, it's complicated.
Today we're announcing *part* of Functions - Supabase Hooks - in Alpha, for all **new** projects.
Today we're announcing _part_ of Functions - Supabase Hooks - in Alpha, for all **new** projects.
We're also releasing support for Postgres Functions and Triggers in our Dashboard, and some timelines for the rest of Supabase Functions.
Let's cover the features we're launching today before the item that everyone is waiting for: Supabase Functions.
## PostgreSQL Functions
(Not to be confused with Supabase Functions!)
(Not to be confused with Supabase Functions!)
Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html). Today we're making it even easier for developers to build PostgreSQL Functions by releasing a native Functions editor. Soon we'll release some handy templates!
![Postgres Functions](/new/images/blog/functions-updates/postgres-functions.png)
![Postgres Functions](/images/blog/functions-updates/postgres-functions.png)
You can call PostgreSQL Functions with `supabase-js` using your project API [[Docs](https://supabase.io/docs/reference/javascript/rpc)]:
```js hideCopy
const { data, error } = await supabase
.rpc('best_star_wars_series', {
name: 'The Prequels'
})
const { data, error } = await supabase.rpc('best_star_wars_series', {
name: 'The Prequels',
})
```
## PostgreSQL Triggers
@@ -47,84 +43,84 @@ const { data, error } = await supabase
While triggers are a staple of Database Administrators, they can be a bit complex and hard to use. We plan to change that with a simple interface for building and managing PostgreSQL triggers.
![Postgres Triggers](/new/images/blog/functions-updates/postgres-triggers.png)
![Postgres Triggers](/images/blog/functions-updates/postgres-triggers.png)
## Supabase Functions
They say building a startup is like jumping off a cliff and assembling the plane on the way down. At Supabase it's more like assembling a 747 since, although we're still in Beta, thousands of companies depend on us to power their apps and websites.
For the past few months we've been designing Supabase Functions based on our customer feedback.
For the past few months we've been designing Supabase Functions based on our customer feedback.
### BYO Functions, zero lock-in
A recurring request from our customers is the ability to trigger their *existing* Functions.
A recurring request from our customers is the ability to trigger their _existing_ Functions.
This is especially true for our Enterprise customers, but also Jamstack developers who develop API Functions directly within their stack (like Next.js [API routes](https://nextjs.org/docs/api-routes/introduction), or Redwood [Serverless Functions](https://redwoodjs.com/docs/serverless-functions)).
### Timeline
To meet these goals, we're releasing Supabase Functions in stages:
- *Stage 1:* Give developers the ability to trigger external HTTP functions - today, using Function Hooks.
- *Stage 2:* Give developers the ability to trigger their own Serverless functions on AWS and GCP - Q4 2021.
- *Stage 3:* Release our own Serverless Functions (Supabase Functions) - Q4 for Early Preview customers.
- _Stage 1:_ Give developers the ability to trigger external HTTP functions - today, using Function Hooks.
- _Stage 2:_ Give developers the ability to trigger their own Serverless functions on AWS and GCP - Q4 2021.
- _Stage 3:_ Release our own Serverless Functions (Supabase Functions) - Q4 for Early Preview customers.
![Supabase Functions timeline](/new/images/blog/functions-updates/functions-timeline.png)
![Supabase Functions timeline](/images/blog/functions-updates/functions-timeline.png)
## Function Hooks (Alpha)
Today we're releasing Functions Hooks in `ALPHA`. The `ALPHA` tag means that it is NOT stable, but it's available for testing and feedback. The API will change, so do not use it for anything critical. You have been warned.
Today we're releasing Functions Hooks in `ALPHA`. The `ALPHA` tag means that it is NOT stable, but it's available for testing and feedback. The API will change, so do not use it for anything critical. You have been warned.
Hooks? Triggers? Firestore has the concept of [Function Triggers](https://firebase.google.com/docs/functions/firestore-events), which are very cool.
Supabase Hooks are the same concept, just with a different name.
Postgres already has the concept of [Triggers](https://www.postgresql.org/docs/current/triggers.html), and we thought this would be less confusing[^1].
Hooks? Triggers? Firestore has the concept of [Function Triggers](https://firebase.google.com/docs/functions/firestore-events), which are very cool.
Supabase Hooks are the same concept, just with a different name.
Postgres already has the concept of [Triggers](https://www.postgresql.org/docs/current/triggers.html), and we thought this would be less confusing[^1].
### Hook Events
Function Hooks allow you to "listen" to any change in your tables to trigger an asynchronous Function. You can hook into a few different events:`INSERT`, `UPDATE`, and `DELETE`. All events are fired **after** a database row is changed. Keen eyes will be able to spot the similarity to Postgres triggers, and that's because Function Hooks are just a convenience wrapper around triggers.
![Hook Events](/new/images/blog/functions-updates/hook-events.png)
![Hook Events](/images/blog/functions-updates/hook-events.png)
### Hook Targets
Supabase will support several different targets.
- HTTP/Webhooks: Send HTTP requests directly from your Postgres Database.
- AWS Lambda/Google Cloud Run: Provide Supabase with a restricted IAM role to trigger Serverless functions natively.
- AWS Lambda/Google Cloud Run: Provide Supabase with a restricted IAM role to trigger Serverless functions natively.
- Supabase Functions: We'll develop an end-to-end experience.
![Supabase Function Hooks](/new/images/blog/functions-updates/supabase-function-hooks.png)
![Supabase Function Hooks](/images/blog/functions-updates/supabase-function-hooks.png)
### Hook Payload
If the target is a Serverless function or an HTTP `POST` request, the payload is automatically generated from the underlying table data. The format matches Supabase [Realtime](https://supabase.io/docs/reference/javascript/subscribe), except in this case you don't a client to "listen" to the changes. This provides yet another mechanism for responding to database changes.
If the target is a Serverless function or an HTTP `POST` request, the payload is automatically generated from the underlying table data. The format matches Supabase [Realtime](https://supabase.io/docs/reference/javascript/subscribe), except in this case you don't a client to "listen" to the changes. This provides yet another mechanism for responding to database changes.
```ts hideCopy
type InsertPayload = {
type: 'INSERT'
table: string
schema: string
record: TableRecord<T>
old_record: null
type: 'INSERT'
table: string
schema: string
record: TableRecord<T>
old_record: null
}
type UpdatePayload = {
type: 'UPDATE'
table: string
schema: string
record: TableRecord<T>
old_record: TableRecord<T>
type: 'UPDATE'
table: string
schema: string
record: TableRecord<T>
old_record: TableRecord<T>
}
type DeletePayload = {
type: 'DELETE'
table: string
schema: string
record: null
old_record: TableRecord<T>
type: 'DELETE'
table: string
schema: string
record: null
old_record: TableRecord<T>
}
```
## Hooks technical design: `pg_net v0.1`
As with most of the Supabase platform, we leverage PostgreSQL's native functionality to implement Function Hooks.
As with most of the Supabase platform, we leverage PostgreSQL's native functionality to implement Function Hooks.
To build hooks, we've released a new PostgreSQL Extension, [pg_net](https://github.com/supabase/pg_net/), an asynchronous networking extension with an emphasis on scalability/throughput. In its initial (unstable) release we expose:
@@ -151,15 +147,15 @@ http_post
1
```
After making a request, the extension will return an ID. You can use this ID to collect a response.
After making a request, the extension will return an ID. You can use this ID to collect a response.
```sql noCopy
-- Collect the response from a request
select
*
from
select
*
from
net.http_collect_response(1);
-- Results (1 row)
status | message | response
--------+---------+----------
@@ -175,12 +171,13 @@ You can cast the response to JSON within PostgreSQL:
```sql
-- Collect the response json payload from a request
select
(response).body::json
from
net.http_collect_response(request_id:=1);
(response).body::json
from
net.http_collect_response(request_id:=1);
```
Result:
```json noCopy
{
"args": {},
@@ -214,20 +211,20 @@ Shout out to [Paul Ramsey](https://github.com/pramsey), who gave us the implemen
\timing on
-- using pgsql-http to fetch from "supabase.io" 10 times
select
*
from
http_get('https://supabase.io')
cross join
select
*
from
http_get('https://supabase.io')
cross join
generate_series(1, 10) _;
-- Returns in 3.5 seconds
Time: 3501.935 ms
-- using pg_net to fetch from "supabase.io" 10 times
select
net.http_get('https://supabase.io')
from
select
net.http_get('https://supabase.io')
from
generate_series (1,10) _;
-- Returns in 1.5 milliseconds
@@ -249,7 +246,6 @@ This is only the beginning! First we'll thoroughly test it and make a stable rel
Function Hooks is enabled today on all [new projects](https://app.supabase.io). Find it under Database > Alpha Preview > Function Hooks.
![Enable hooks](/new/images/blog/functions-updates/enable-hooks.png)
![Enable hooks](/images/blog/functions-updates/enable-hooks.png)
[^1]: Postgres also has the concept of [Hooks](https://supabase.io/blog/2021/07/01/roles-postgres-hooks), but they're more of an internal concept.
[^1]: Postgres also has the concept of [Hooks](https://supabase.io/blog/2021/07/01/roles-postgres-hooks), but they're more of an internal concept.
+14 -16
View File
@@ -16,20 +16,18 @@ toc_depth: 3
Today we are officially [launching the Supabase Swag Store](https://store.supabase.com/).
Since we started gifting swag, we are constantly asked, "when will you launch a store?".
We take our swag game seriously. We're as hands-on with our swag as we are with our repos.
Since we started gifting swag, we are constantly asked, "when will you launch a store?".
We take our swag game seriously. We're as hands-on with our swag as we are with our repos.
When you receive an item of swag from Supabase, you can be confident that we designed it, managed the production, packed it, and posted it.
This process often means late nights for the team, making sure things are packed and ready to dispatch for the next day.
This process often means late nights for the team, making sure things are packed and ready to dispatch for the next day.
Why? Because we want to offer high-quality swag to our users.
![Swag Shipping](/new/images/blog/swag-store/swag-shipping.jpg)
![Swag Shipping](/images/blog/swag-store/swag-shipping.jpg)
## Swaggable Behavior
Our primary goal with swag is gifting. We send swag to developers who make meaningful contributions to Supabase in a variety of ways.
Our primary goal with swag is gifting. We send swag to developers who make meaningful contributions to Supabase in a variety of ways.
This includes:
- 📺 Creating Supabase related content.
@@ -39,23 +37,23 @@ This includes:
- 📲 Advocates who share Supabase related content on social media.
- 📚 Developers who contribute to open source libraries
![Swag Winners](/new/images/blog/swag-store/swag-winners.png)
![Swag Winners](/images/blog/swag-store/swag-winners.png)
For example, [Hassan's tweet caught our eye](https://twitter.com/Nutlope/status/1389082406477463557) because the idea is
innovative and uses Supabase as part of an interesting tech stack. We are amazed by the creative use cases you all find for Supabase.
For example, [Hassan's tweet caught our eye](https://twitter.com/Nutlope/status/1389082406477463557) because the idea is
innovative and uses Supabase as part of an interesting tech stack. We are amazed by the creative use cases you all find for Supabase.
We love it when folks #buildinpublic and share open-source examples that benefit the entire community.
We do our best to identify members of the community engaging in these "swaggable behavior".
We don't have a specific benchmark for these activities. We can say, if you are engaging in these behaviors regularly,
then our Chief Swag Officer will find you and will get swag to you. We also like to do occasional random giveaways to
We do our best to identify members of the community engaging in these "swaggable behavior".
We don't have a specific benchmark for these activities. We can say, if you are engaging in these behaviors regularly,
then our Chief Swag Officer will find you and will get swag to you. We also like to do occasional random giveaways to
show some love for folks in the conversation. We will continue to announce these via Twitter and Discord.
![I will find you](/new/images/blog/swag-store/i-will-find-you-meme.jpg)
![I will find you](/images/blog/swag-store/i-will-find-you-meme.jpg)
We have had significant demand from users who just wanted to rock some Supabase swag.
We have had significant demand from users who just wanted to rock some Supabase swag.
So, we decided to launch the [Supabase Swag Store](https://store.supabase.com/).
We will put our hands up here and tell you we built the store using Shopify. We couldn't dogfood an entire eCommerce store.
We will put our hands up here and tell you we built the store using Shopify. We couldn't dogfood an entire eCommerce store.
Shopify is good enough, and we wanted to go live with this as part of launch week 🚀 👩‍🚀
Due to the lack of outsourcing, we need to highlight several things about the Supabase store:
+13 -13
View File
@@ -29,15 +29,15 @@ Don't forget that all the projects here are Open Source, so you can always dive
Josh's project allows employees to log which days and hours they'll be working and gives everyone on the team and within the company an overview of who is working when. The animations, UI/UX of this submission combined with the fact that it was built within a single week was absolutely mind-blowing!
[![Work From](/new/images/blog/hackathon-winners/projects/workday.png)](https://github.com/joshcawthorne/work-from)
[![Work From](/images/blog/hackathon-winners/projects/workday.png)](https://github.com/joshcawthorne/work-from)
### Runner Up
[Fireplace](https://github.com/0xDebabrata/fireplace) - by [@0xDebabrata](https://twitter.com/0xDebabrata), [@_anishbasu](https://twitter.com/_anishbasu), [@DebMondalX](https://github.com/DebMondalX)
[Fireplace](https://github.com/0xDebabrata/fireplace) - by [@0xDebabrata](https://twitter.com/0xDebabrata), [@\_anishbasu](https://twitter.com/_anishbasu), [@DebMondalX](https://github.com/DebMondalX)
Fireplace makes great use of Supabase Storage for a shared video streaming experience, the killer feature here was the ability to share play, pause, and skip events across multiple users.
[![Fireplace](/new/images/blog/hackathon-winners/projects/fireplace.png)](https://github.com/0xDebabrata/fireplace)
[![Fireplace](/images/blog/hackathon-winners/projects/fireplace.png)](https://github.com/0xDebabrata/fireplace)
## Most Visually Pleasing
@@ -45,9 +45,9 @@ Fireplace makes great use of Supabase Storage for a shared video streaming exper
[Flutter Dictionary App](https://github.com/KathirvelChandrasekaran/dictionary_app) - by [@KathirvelChandrasekaran](https://github.com/KathirvelChandrasekaran)
The judges found the design of this Flutter app to be super impressive, the animations and color palette are especially top drawer!
The judges found the design of this Flutter app to be super impressive, the animations and color palette are especially top drawer!
[![Dictionary](/new/images/blog/hackathon-winners/projects/dictionary.png)](https://github.com/KathirvelChandrasekaran/dictionary_app)
[![Dictionary](/images/blog/hackathon-winners/projects/dictionary.png)](https://github.com/KathirvelChandrasekaran/dictionary_app)
### Runner Up
@@ -55,7 +55,7 @@ The judges found the design of this Flutter app to be super impressive, the anim
Tyler's app allows you to come together and chat with strangers in the browser, the feature we loved most was the randomized avatar generation (click the button in the top right to try it out)
[![tyler chat](/new/images/blog/hackathon-winners/projects/tyler.png)](https://github.com/dshukertjr/avatar-village)
[![tyler chat](/images/blog/hackathon-winners/projects/tyler.png)](https://github.com/dshukertjr/avatar-village)
## Most Technically Challenging
@@ -65,7 +65,7 @@ Tyler's app allows you to come together and chat with strangers in the browser,
Boss work from Richie here - simply add a snippet to your app, then build and manage the components of your application from the Feature dashboard. An amazing example of where no-code is going.
[![Feature dot so](/new/images/blog/hackathon-winners/projects/featureso.png)](https://github.com/richiemcilroy/feature)
[![Feature dot so](/images/blog/hackathon-winners/projects/featureso.png)](https://github.com/richiemcilroy/feature)
### Runner Up
@@ -73,7 +73,7 @@ Boss work from Richie here - simply add a snippet to your app, then build and ma
Hook up your supabase credentials and Flutter app and Add-ons will start collecting metrics, analytics, and crashalytics, all in a neat dashboard with great visualization tools. Unbelievable that bdlukaa was able to build this in the space of a week.
[![Add Ons](/new/images/blog/hackathon-winners/projects/addons.png)](https://github.com/bdlukaa/supabase_addons)
[![Add Ons](/images/blog/hackathon-winners/projects/addons.png)](https://github.com/bdlukaa/supabase_addons)
## Most Fun/Interesting
@@ -83,7 +83,7 @@ Hook up your supabase credentials and Flutter app and Add-ons will start collect
Add at 4 or more ingredients to your list and Peckish Peach will use ML to generate a full recipe. You can have some real fun adding random foods together and seeing what the algo comes up with. Bonus points for the adorable Peach gif!
[![Peach recipes](/new/images/blog/hackathon-winners/projects/peach1.png)](https://github.com/Ngineer101/peckish-peach)
[![Peach recipes](/images/blog/hackathon-winners/projects/peach1.png)](https://github.com/Ngineer101/peckish-peach)
### Runner Up
@@ -91,7 +91,7 @@ Add at 4 or more ingredients to your list and Peckish Peach will use ML to gener
Instagram for Pets! The best bit is all the interactions inside the app are from the perspective of your pet. We were loving the Tamagotchi throwback!
[![tamogochi real insta](/new/images/blog/hackathon-winners/projects/tamog.png)](https://github.com/mgilangjanuar/tamagotreal)
[![tamogochi real insta](/images/blog/hackathon-winners/projects/tamog.png)](https://github.com/mgilangjanuar/tamagotreal)
## Best Meme
@@ -105,13 +105,13 @@ This cheeky one from lautaro had us tickled.
[Multiple Memes](https://github.com/rotimi-best/sveltedoc) - by [@rotimi-best](https://github.com/rotimi-best)
![meme runner up 2](/new/images/blog/hackathon-winners/misc/meme3.jpg) - by [@wycowley](https://github.com/wycowley), by [@SonavAgarwal](https://github.com/SonavAgarwal)
![meme runner up 2](/images/blog/hackathon-winners/misc/meme3.jpg) - by [@wycowley](https://github.com/wycowley), by [@SonavAgarwal](https://github.com/SonavAgarwal)
## The Prizes
All gold medal winners will be contacted and sent one of these limited edition gold Supabase tees (one per team member), and all runners up will receive the same design in silver. Prize winners should keep an eye on their emails so we can collect T-Shirt size and shipping details.
![Gold Tshirt](/new/images/blog/hackathon/tshirt.png)
![Gold Tshirt](/images/blog/hackathon/tshirt.png)
### Other Notable Projects
@@ -140,7 +140,7 @@ If you want to join the community and build with us, find other people using Sup
[Join our Discord](https://discord.supabase.com)
![Discord Hangout](/new/images/blog/hackathon/community.png)
![Discord Hangout](/images/blog/hackathon/community.png)
### Get Started Guides
@@ -31,102 +31,102 @@ Watch a full demo of this month's releases.
## Launch Week II: The SQL
Following the success of our first Launch Week in March, we finished the July with "[Launch Week II: The SQL](/blog/2021/07/22/supabase-launch-week-sql)".
Following the success of our first Launch Week in March, we finished the July with "[Launch Week II: The SQL](/blog/2021/07/22/supabase-launch-week-sql)".
The community has been sieving through a slew of bad puns and retro memes to discover the new feature announcements.
![Launch Week II: The SQL](/new/images/blog/2021-july/supabase-launch-the-sql.png)
![Launch Week II: The SQL](/images/blog/2021-july/supabase-launch-the-sql.png)
## Auth v2 with Phone Auth
Your users can now log in with SMS based mobile auth! We have a Twilio integration ([Guide Here](https://supabase.io/docs/guides/auth/auth-twilio)) and will be adding more providers soon.
Other Auth updating include, Twitch logins, and the ability to generate invite, recovery, confirmation, and magic links via the API,
Other Auth updating include, Twitch logins, and the ability to generate invite, recovery, confirmation, and magic links via the API,
for people who want more control over the email templating flow. Read the [blog post here](https://supabase.io/blog/2021/07/28/supabase-auth-passwordless-sms-login).
![Auth v2 with Phone Auth](/new/images/blog/2021-july/verify-phone.jpg)
![Auth v2 with Phone Auth](/images/blog/2021-july/verify-phone.jpg)
## Storage is now in Beta
Storage updates include Media Streaming, Public Buckets, Directory Uploads, and a Performance Improvements.
Storage updates include Media Streaming, Public Buckets, Directory Uploads, and a Performance Improvements.
Streaming Media in particular opens up a whole new host of potential use cases, learn more about the [updates here](https://supabase.io/blog/2021/07/27/storage-beta).
![Auth v2 with Phone Auth](/new/images/blog/2021-july/storage.png)
![Auth v2 with Phone Auth](/images/blog/2021-july/storage.png)
## Dashboard v2
We made some major new additions to the dashboard including usage statistics, a new project home, and tons of database insights.
We made some major new additions to the dashboard including usage statistics, a new project home, and tons of database insights.
Check the [post here](https://supabase.io/blog/2021/07/29/supabase-reports-and-metrics) on what you get and how we built it.
![Dashboard v2](/new/images/blog/2021-july/dashboards.png)
![Dashboard v2](/images/blog/2021-july/dashboards.png)
## We launched a Discord server
You'll find us hanging out regularly in the #hangout channel.
We even "live-fixed" some production errors in there on Monday night (which occurred literally 1 hour before our first announcement of the week! Typical!).
You'll find us hanging out regularly in the #hangout channel.
We even "live-fixed" some production errors in there on Monday night (which occurred literally 1 hour before our first announcement of the week! Typical!).
We're fast approaching 1,500 members so come and join the action! [discord.supabase.com](https://discord.supabase.com)
![We launched a Discord server](/new/images/blog/2021-july/discord.png)
![We launched a Discord server](/images/blog/2021-july/discord.png)
## PostgreSQL 13
All new Supabase projects will be launched with PostgreSQL 13.3, and we're working on a migration path for old projects.
All new Supabase projects will be launched with PostgreSQL 13.3, and we're working on a migration path for old projects.
This gives you [looooaads of new stuff out the box](https://supabase.io/blog/2021/07/26/supabase-postgres-13).
![PostgreSQL 13](/new/images/blog/2021-july/postgres-13.png)
![PostgreSQL 13](/images/blog/2021-july/postgres-13.png)
## PostgREST v8.0
We worked with our friends at [PostgREST](https://postgrest.org/) to make some [huge improvements](https://supabase.io/blog/2021/07/26/supabase-community-day#postgrest-version-80).
For those of you who don't know, every Supabase instance comes with a dedicated PostgREST server by default,
We worked with our friends at [PostgREST](https://postgrest.org/) to make some [huge improvements](https://supabase.io/blog/2021/07/26/supabase-community-day#postgrest-version-80).
For those of you who don't know, every Supabase instance comes with a dedicated PostgREST server by default,
which provides the auto-generated CRUD API that we wrap with `supabase-js`.
![PostgREST v8.0](/new/images/blog/2021-july/postgrest-8.png)
![PostgREST v8.0](/images/blog/2021-july/postgrest-8.png)
## Flutter/Dart support
Our community driven libs for the fasted growing mobile and web framework are now in beta. Learn more by following the [Quickstart guide](https://supabase.io/docs/guides/with-flutter).
![Flutter/Dart support](/new/images/blog/2021-july/dart.png)
![Flutter/Dart support](/images/blog/2021-july/dart.png)
## Hackathon
We're running a week long hackathon starting NOW. There are some legit prizes, and you can win in a bunch of different categories.
We're running a week long hackathon starting NOW. There are some legit prizes, and you can win in a bunch of different categories.
Check the [full instructions here](https://supabase.io/blog/2021/07/30/1-the-supabase-hackathon) on how to participate. Submissions close next Friday at midnight PST.
![Hackathon](/new/images/blog/2021-july/hackathon.png)
![Hackathon](/images/blog/2021-july/hackathon.png)
## Hooks & Functions
We made an announcement on the progress of functions, and even shipped a few preliminary components, try them out and give us feedback as we continue to move towards this next major milestone.
We made an announcement on the progress of functions, and even shipped a few preliminary components, try them out and give us feedback as we continue to move towards this next major milestone.
Read the latest [updates here](https://supabase.io/blog/2021/07/30/supabase-functions-updates).
![Hooks & Functions](/new/images/blog/2021-july/hooks.jpg)
![Hooks & Functions](/images/blog/2021-july/hooks.jpg)
## Swag Store
Get your hands on some [Supabase Swag](https://store.supabase.com/), hand packed and mailed by our team based in Singapore.
![Swag Store](/new/images/blog/2021-july/swag.png)
![Swag Store](/images/blog/2021-july/swag.png)
## Community
- [@traversymedia](https://twitter.com/traversymedia) made a [Supabase Crash Course](https://www.youtube.com/watch?v=7uKQBl9uZ00) video
- [@themarcusbattle](https://twitter.com/themarcusbattle/status/1419638564573360130?s=20) wrote a [guide](https://www.twilio.com/blog/send-sms-notifications-supabase-users-node-js-twilio-messaging) on sending sms notifications using node.js, Twilio, and Supabase (this is different to sms auth above)
- [@dots_hq](https://twitter.com/dots_hq) launched a slack/discord [community management tool](https://dots.community/) built on Supabase
- [@traversymedia](https://twitter.com/traversymedia) made a [Supabase Crash Course](https://www.youtube.com/watch?v=7uKQBl9uZ00) video
- [@themarcusbattle](https://twitter.com/themarcusbattle/status/1419638564573360130?s=20) wrote a [guide](https://www.twilio.com/blog/send-sms-notifications-supabase-users-node-js-twilio-messaging) on sending sms notifications using node.js, Twilio, and Supabase (this is different to sms auth above)
- [@dots_hq](https://twitter.com/dots_hq) launched a slack/discord [community management tool](https://dots.community/) built on Supabase
- [@KennethCassel](https://twitter.com/KennethCassel) launched a [platform for building programming courses](https://www.slip.so/) using Supabase
- [@MobbinDesign](https://twitter.com/MobbinDesign) migrated their UI/UX library app to Supabase, currently [serving 200,000 users](https://supabase.io/blog/2021/07/28/mobbin-supabase-200000-users)
- [@MobbinDesign](https://twitter.com/MobbinDesign) migrated their UI/UX library app to Supabase, currently [serving 200,000 users](https://supabase.io/blog/2021/07/28/mobbin-supabase-200000-users)
- To the amazing users who are helping moderate our discord server, ya'll are amazing
**Supabase Github Star Growth** 
**Supabase Github Star Growth**
![14200 stars on GitHub.](/new/images/blog/2021-july/github-growth.png)
![14200 stars on GitHub.](/images/blog/2021-july/github-growth.png)
<small>
Source: <a href="https://repository.surf/supabase">repository.surf/supabase</a>
</small>
If you want to keep up to date, make sure you [subscribe to our YouTube channel](https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ) or
If you want to keep up to date, make sure you [subscribe to our YouTube channel](https://www.youtube.com/channel/UCNTVzV1InxHV-YR0fSajqPQ) or
[follow us on Twitter](https://twitter.com/supabase).
## Coming Next
Loaded 100 of 168 files, more files were not shown because too many files have changed in this diff. Show more